diff --git a/cmdline/mingw.c b/cmdline/mingw.c index d111442c..f8a09a0e 100644 --- a/cmdline/mingw.c +++ b/cmdline/mingw.c @@ -223,11 +223,6 @@ void os_init(int opt) exedir_init(); - /* set stdout and stderr as "line buffered" */ - /* this ensures that messages are mixed correctly */ - setvbuf(stdout, 0, _IOLBF, BUFSIZ); - setvbuf(stderr, 0, _IOLBF, BUFSIZ); - last_error = 0; } diff --git a/cmdline/parity.c b/cmdline/parity.c index 51138819..598a6120 100644 --- a/cmdline/parity.c +++ b/cmdline/parity.c @@ -136,13 +136,13 @@ void parity_overflow(struct snapraid_state* state, data_off_t size) if (file->blockmax > 0) { if (file->blockvec[file->blockmax - 1].parity_pos >= blockalloc) { msg_tag("outofparity:%s:%s\n", disk->name, esc(file->sub)); - msg_flush(); if (first) { first = 0; msg_warning("\nYour data requires more parity than the available space.\n"); msg_warning("Please move the files 'outofparity' to another data disk:\n"); } msg_warning("outofparity %s%s\n", disk->dir, file->sub); + msg_flush(); } } } diff --git a/cmdline/state.c b/cmdline/state.c index 4de88cd9..4e268fcf 100644 --- a/cmdline/state.c +++ b/cmdline/state.c @@ -930,7 +930,6 @@ void state_config(struct snapraid_state* state, const char* path, const char* co } if (state->filter_hidden) msg_tag("filter:nohidden:\n"); - msg_flush(); } @@ -4633,6 +4632,7 @@ void state_progress_end(struct snapraid_state* state, block_off_t countpos, bloc if (elapsed >= 60) msg_bar(" in %u:%02u", (unsigned)(elapsed / 3600), (unsigned)((elapsed % 3600) / 60)); msg_bar("\n"); + msg_flush(); } } @@ -4642,8 +4642,10 @@ void state_progress_stop(struct snapraid_state* state) now = time(0); - if (!state->opt.gui) + if (!state->opt.gui) { msg_bar("\n"); + msg_flush(); + } state->progress_interruption = now; } @@ -4759,7 +4761,7 @@ int state_progress(struct snapraid_state* state, block_off_t blockpos, block_off if (out_eta) msg_bar(", %u:%02u ETA", out_eta / 60, out_eta % 60); msg_bar("%s\r", PROGRESS_CLEAR); - fflush(stdout); + msg_flush(); } /* store the new measure */ diff --git a/cmdline/support.c b/cmdline/support.c index 4e6349fd..499b4146 100644 --- a/cmdline/support.c +++ b/cmdline/support.c @@ -24,13 +24,22 @@ int msg_level = 0; +/* + * Note that in the following functions we always flush both + * stdout and stderr, because we want to ensure that they mixes + * well when redirected to files + * + * The buffering is similar at the "line buffered" one, that + * is not available on Windows, so we emulate it in this way. + * + * For stdlog the flush is only limited. + * To ensure flushing the caller should use msg_flush(). + */ + void msg_error(const char* format, ...) { va_list ap; - /* first output the same message to stdlog and flush it */ - /* to avoid to mix messages in case streams are redirected */ - /* to the same file */ if (stdlog) { va_start(ap, format); fprintf(stdlog, "msg:error: "); @@ -41,6 +50,7 @@ void msg_error(const char* format, ...) va_start(ap, format); vfprintf(stderr, format, ap); + fflush(stderr); va_end(ap); } @@ -52,10 +62,12 @@ void msg_warning(const char* format, ...) va_start(ap, format); fprintf(stdlog, "msg:warning: "); vfprintf(stdlog, format, ap); + fflush(stdlog); va_start(ap, format); } else { va_start(ap, format); vfprintf(stderr, format, ap); + fflush(stderr); va_start(ap, format); } } @@ -75,20 +87,18 @@ void msg_status(const char* format, ...) { va_list ap; - /* first output the same message to stdlog and flush it */ - /* to avoid to mix messages in case streams are redirected */ - /* to the same file */ if (stdlog) { va_start(ap, format); fprintf(stdlog, "msg:status: "); vfprintf(stdlog, format, ap); - va_end(ap); fflush(stdlog); + va_end(ap); } if (msg_level >= MSG_STATUS) { va_start(ap, format); vfprintf(stdout, format, ap); + fflush(stdout); va_end(ap); } } @@ -103,6 +113,7 @@ void msg_info(const char* format, ...) if (msg_level >= MSG_INFO) { va_start(ap, format); vfprintf(stdout, format, ap); + fflush(stdout); va_end(ap); } } @@ -111,20 +122,18 @@ void msg_progress(const char* format, ...) { va_list ap; - /* first output the same message to stdlog and flush it */ - /* to avoid to mix messages in case streams are redirected */ - /* to the same file */ if (stdlog) { va_start(ap, format); fprintf(stdlog, "msg:progress: "); vfprintf(stdlog, format, ap); - va_end(ap); fflush(stdlog); + va_end(ap); } if (msg_level >= MSG_PROGRESS) { va_start(ap, format); vfprintf(stdout, format, ap); + fflush(stdout); va_end(ap); } } @@ -135,6 +144,7 @@ void msg_bar(const char* format, ...) /* don't output in stdlog as these messages */ /* are intended for screen only */ + /* also don't flush stdout as they are intended to be partial messages */ if (msg_level >= MSG_BAR) { va_start(ap, format); @@ -147,20 +157,18 @@ void msg_verbose(const char* format, ...) { va_list ap; - /* first output the same message to stdlog and flush it */ - /* to avoid to mix messages in case streams are redirected */ - /* to the same file */ if (stdlog) { va_start(ap, format); fprintf(stdlog, "msg:verbose: "); vfprintf(stdlog, format, ap); - va_end(ap); fflush(stdlog); + va_end(ap); } if (msg_level >= MSG_VERBOSE) { va_start(ap, format); vfprintf(stdout, format, ap); + fflush(stdout); va_end(ap); } } @@ -170,6 +178,7 @@ void msg_flush(void) if (stdlog) fflush(stdlog); fflush(stdout); + fflush(stderr); } /** diff --git a/cmdline/support.h b/cmdline/support.h index 196eea36..8ed9bda3 100644 --- a/cmdline/support.h +++ b/cmdline/support.h @@ -50,6 +50,8 @@ void msg_warning(const char* format, ...) __attribute__((format(attribute_printf * These messages neves go on the screen, but only in the log file if specified. * * Note that this function, allows not \n terminated strings. + * + * These messages are buffered. Use msg_flush() to flush them. */ void msg_tag(const char* format, ...) __attribute__((format(attribute_printf, 1, 2))); @@ -106,6 +108,8 @@ void msg_progress(const char* format, ...) __attribute__((format(attribute_print * Message that show the percentage of the progress. * * These messages never go in the log file. + * + * These messages are buffered. Use msg_flush() to flush them. */ void msg_bar(const char* format, ...) __attribute__((format(attribute_printf, 1, 2))); diff --git a/cmdline/unix.c b/cmdline/unix.c index 04789407..9a66213b 100644 --- a/cmdline/unix.c +++ b/cmdline/unix.c @@ -958,11 +958,6 @@ int devquery(tommy_list* high, tommy_list* low, int operation) void os_init(int opt) { (void)opt; - - /* set stdout and stderr as "line buffered" */ - /* this ensures that messages are mixed correctly */ - setvbuf(stdout, 0, _IOLBF, BUFSIZ); - setvbuf(stderr, 0, _IOLBF, BUFSIZ); } void os_done(void)