Avoid duplicate fatal stderr output in GUI mode

This commit is contained in:
Andrea Mazzoleni 2026-09-17 18:20:27 +02:00
parent d0194c3aff
commit ecb12ee92c
6 changed files with 51 additions and 18 deletions

View file

@ -178,16 +178,18 @@ void log_open(const char* file)
void log_close(const char* file)
{
if (stdlog != stdout && stdlog != stderr && stdlog != 0) {
if (fclose(stdlog) != 0) {
FILE* log = stdlog;
/* fclose() invalidates the stream even on error, so fatal reporting must use stderr. */
stdlog = 0;
if (log != stdout && log != stderr && log != 0) {
if (fclose(log) != 0) {
/* LCOV_EXCL_START */
log_fatal(errno, "Error closing the log file '%s'. %s.\n", file, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
}
stdlog = 0;
}
/****************************************************************************/
@ -1065,6 +1067,8 @@ int snapraid_main(int argc, char* argv[])
}
}
msg_fatal_stderr = !opt.gui;
os_init(OS_INIT_OPT_AVOID_SLEEP | (opt.force_scan_winfind ? OS_INIT_OPT_WINFIND : 0));
app_init();
raid_init();

View file

@ -293,6 +293,7 @@ void log_error_errno(int err, const char* name)
/* print */
int msg_level = 0;
int msg_fatal_stderr = 1;
FILE* stdlog = 0;
int msg_line_prev = 0; /**< Previous line width on stdout */
int msg_line_curr = 0; /**< Current line width on stdout */
@ -374,34 +375,41 @@ static void msg(FILE* out, const char* format, ...)
void vlog_fatal(int err, const char* format, va_list ap, const char* post)
{
int log_failed = 0;
lock_msg();
if (stdlog) {
if (is_hw(err))
fprintf(stdlog, "msg:fatal_hardware: ");
log_failed = fprintf(stdlog, "msg:fatal_hardware: ") < 0;
else
fprintf(stdlog, "msg:fatal: ");
log_failed = fprintf(stdlog, "msg:fatal: ") < 0;
va_list ap_copy;
va_copy(ap_copy, ap);
vfprintf(stdlog, format, ap_copy);
if (vfprintf(stdlog, format, ap_copy) < 0)
log_failed = 1;
va_end(ap_copy);
if (post)
fprintf(stdlog, "%s", post);
if (post && fprintf(stdlog, "%s", post) < 0)
log_failed = 1;
fflush(stdlog);
if (fflush(stdlog) != 0)
log_failed = 1;
}
va_list ap_copy2;
va_copy(ap_copy2, ap);
vmsg(stderr, format, ap_copy2);
va_end(ap_copy2);
/* A failed tagged write must retain stderr as the only usable fatal diagnostic. */
if (!stdlog || log_failed || msg_fatal_stderr) {
va_list ap_copy2;
va_copy(ap_copy2, ap);
vmsg(stderr, format, ap_copy2);
va_end(ap_copy2);
if (post)
msg(stderr, "%s", post);
if (post)
msg(stderr, "%s", post);
fflush(stderr);
fflush(stderr);
}
unlock_msg();
}

View file

@ -92,7 +92,8 @@ typedef void log_ptr(int err, const char* format, ...) __attribute__((format(att
*
* Messages printed before an early termination.
*
* These messages go in the log file and in stderr unconditionally.
* These messages go in the log file and in stderr, except in GUI mode
* when the tagged log message is emitted successfully.
*/
void vlog_fatal(int err, const char* format, va_list ap, const char* post);
void log_fatal(int err, const char* format, ...) __attribute__((format(attribute_printf, 2, 3)));
@ -176,6 +177,11 @@ typedef void msg_ptr(const char* format, ...) __attribute__((format(attribute_pr
*/
extern int msg_level;
/**
* Emit fatal messages on stderr also when a log is configured.
*/
extern int msg_fatal_stderr;
/**
* State messages.
*