// don't do anything if the user is willing
// to have the standard one
- if(!strcmp(filename, "system"))
- return fd;
+ if(!strcmp(filename, "system")) {
+ if(fd != -1) return fd;
+ filename = "stdout";
+ }
if(!strcmp(filename, "stdout"))
f = STDOUT_FILENO;
}
else fd = f;
- if(fp && *fp == NULL) {
- // info("fdopen(%d) on filename '%s'", fd, filename);
-
- FILE *n = fdopen(fd, "a");
- if (!n)
+ if(fp && !*fp) {
+ *fp = fdopen(fd, "a");
+ if (!*fp)
error("Cannot fdopen() fd %d ('%s')", fd, filename);
-
else {
- if (setvbuf(n, NULL, _IOLBF, 0) != 0)
+ if (setvbuf(*fp, NULL, _IOLBF, 0) != 0)
error("Cannot set line buffering on fd %d ('%s')", fd, filename);
-
- if(!*fp)
- *fp = n;
- else {
- FILE *o = *fp;
- *fp = n;
- fclose(o);
- }
}
}
void reopen_all_log_files() {
if(stdout_filename)
- open_log_file(STDOUT_FILENO, &stdout, stdout_filename, &output_log_syslog);
+ open_log_file(STDOUT_FILENO, (FILE **)&stdout, stdout_filename, &output_log_syslog);
if(stderr_filename)
- open_log_file(STDERR_FILENO, &stderr, stderr_filename, &error_log_syslog);
+ open_log_file(STDERR_FILENO, (FILE **)&stderr, stderr_filename, &error_log_syslog);
if(stdaccess_filename)
- stdaccess_fd = open_log_file(stdaccess_fd, &stdaccess, stdaccess_filename, &access_log_syslog);
+ stdaccess_fd = open_log_file(stdaccess_fd, (FILE **)&stdaccess, stdaccess_filename, &access_log_syslog);
}
void open_all_log_files() {
// disable stdin
- open_log_file(STDIN_FILENO, &stdin, "/dev/null", NULL);
+ open_log_file(STDIN_FILENO, (FILE **)&stdin, "/dev/null", NULL);
- open_log_file(STDOUT_FILENO, &stdout, stdout_filename, &output_log_syslog);
- open_log_file(STDERR_FILENO, &stderr, stderr_filename, &error_log_syslog);
- stdaccess_fd = open_log_file(stdaccess_fd, &stdaccess, stdaccess_filename, &access_log_syslog);
+ open_log_file(STDOUT_FILENO, (FILE **)&stdout, stdout_filename, &output_log_syslog);
+ open_log_file(STDERR_FILENO, (FILE **)&stderr, stderr_filename, &error_log_syslog);
+ stdaccess_fd = open_log_file(stdaccess_fd, (FILE **)&stdaccess, stdaccess_filename, &access_log_syslog);
}
// ----------------------------------------------------------------------------
// error log throttling
+time_t error_log_throttle_period_backup = 0;
time_t error_log_throttle_period = 1200;
unsigned long error_log_errors_per_period = 200;
void log_date(FILE *out)
{
- char outstr[24];
+ char outstr[26];
time_t t;
struct tm *tmp, tmbuf;
tmp = localtime_r(&t, &tmbuf);
if (tmp == NULL) return;
- if (unlikely(strftime(outstr, sizeof(outstr), "%y-%m-%d %H:%M:%S", tmp) == 0)) return;
+ if (unlikely(strftime(outstr, sizeof(outstr), "%Y-%m-%d %H:%M:%S", tmp) == 0)) return;
fprintf(out, "%s: ", outstr);
}
log_date(stdout);
va_start( args, fmt );
- printf("DEBUG (%04lu@%-10.10s:%-15.15s): %s: ", line, file, function, program_name);
+ printf("%s: DEBUG (%04lu@%-10.10s:%-15.15s): ", program_name, line, file, function);
vprintf(fmt, args);
va_end( args );
putchar('\n');
log_date(stderr);
va_start( args, fmt );
- if(debug_flags) fprintf(stderr, "INFO (%04lu@%-10.10s:%-15.15s): %s: ", line, file, function, program_name);
- else fprintf(stderr, "INFO: %s: ", program_name);
+ if(debug_flags) fprintf(stderr, "%s: INFO: (%04lu@%-10.10s:%-15.15s):", program_name, line, file, function);
+ else fprintf(stderr, "%s: INFO: ", program_name);
vfprintf( stderr, fmt, args );
va_end( args );
// ----------------------------------------------------------------------------
// error log
+#if defined(STRERROR_R_CHAR_P)
+// GLIBC version of strerror_r
+static const char *strerror_result(const char *a, const char *b) { (void)b; return a; }
+#elif defined(HAVE_STRERROR_R)
+// POSIX version of strerror_r
+static const char *strerror_result(int a, const char *b) { (void)a; return b; }
+#elif defined(HAVE_C__GENERIC)
+
+// what a trick!
+// http://stackoverflow.com/questions/479207/function-overloading-in-c
+static const char *strerror_result_int(int a, const char *b) { (void)a; return b; }
+static const char *strerror_result_string(const char *a, const char *b) { (void)b; return a; }
+
+#define strerror_result(a, b) _Generic((a), \
+ int: strerror_result_int, \
+ char *: strerror_result_string \
+ )(a, b)
+
+#else
+#error "cannot detect the format of function strerror_r()"
+#endif
+
void error_int( const char *prefix, const char *file, const char *function, const unsigned long line, const char *fmt, ... )
{
va_list args;
log_date(stderr);
va_start( args, fmt );
- if(debug_flags) fprintf(stderr, "%s (%04lu@%-10.10s:%-15.15s): %s: ", prefix, line, file, function, program_name);
- else fprintf(stderr, "%s: %s: ", prefix, program_name);
+ if(debug_flags) fprintf(stderr, "%s: %s: (%04lu@%-10.10s:%-15.15s): ", program_name, prefix, line, file, function);
+ else fprintf(stderr, "%s: %s: ", program_name, prefix);
vfprintf( stderr, fmt, args );
va_end( args );
if(errno) {
char buf[1024];
- fprintf(stderr, " (errno %d, %s)\n", errno, strerror_r(errno, buf, 1023));
+ fprintf(stderr, " (errno %d, %s)\n", errno, strerror_result(strerror_r(errno, buf, 1023), buf));
errno = 0;
}
else
log_date(stderr);
va_start( args, fmt );
- if(debug_flags) fprintf(stderr, "FATAL (%04lu@%-10.10s:%-15.15s): %s: ", line, file, function, program_name);
- else fprintf(stderr, "FATAL: %s: ", program_name);
+ if(debug_flags) fprintf(stderr, "%s: FATAL: (%04lu@%-10.10s:%-15.15s): ", program_name, line, file, function);
+ else fprintf(stderr, "%s: FATAL: ", program_name);
vfprintf( stderr, fmt, args );
va_end( args );