X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=lib%2Flog.c;h=0063f3ea7eed13d2239f28f85cda35d8a475d927;hb=4cd590195cb23a667ff5f329a721b6f4ce2e6dc3;hp=e6260b601fe8f34e2772ed1955c0719cac4758e6;hpb=f6d07cf0d75a7d350171039400d2e30e9c56f602;p=libucw.git diff --git a/lib/log.c b/lib/log.c index e6260b60..0063f3ea 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1,7 +1,7 @@ /* - * Sherlock Library -- Logging + * UCW Library -- Logging * - * (c) 1997--2002 Martin Mares + * (c) 1997--2006 Martin Mares * * This software may be freely distributed and used according to the terms * of the GNU Lesser General Public License. @@ -11,73 +11,52 @@ #include #include -#include #include -#include #include +#include #include #include -static char log_progname[32], *log_name_patt, *log_name; -static pid_t log_pid; -static int log_params; -static int log_name_size; -static int log_switching; +static char log_progname[32]; +char *log_filename; +char *log_title; +int log_pid; +int log_precise_timings; +void (*log_die_hook)(void); +void (*log_switch_hook)(struct tm *tm); void -log_fork(void) +vmsg(unsigned int cat, const char *fmt, va_list args) { - log_pid = getpid(); -} - -static void -log_switch(struct tm *tm) -{ - int fd, l; - char name[log_name_size]; - - if (!log_name_patt || - log_name[0] && !log_params || - log_switching) - return; - log_switching++; - l = strftime(name, log_name_size, log_name_patt, tm); - if (l < 0 || l >= log_name_size) - die("Error formatting log file name: %m"); - if (strcmp(name, log_name)) - { - strcpy(log_name, name); - fd = open(name, O_WRONLY | O_CREAT | O_APPEND, 0666); - if (fd < 0) - die("Unable to open log file %s: %m", name); - close(2); - dup(fd); - close(fd); - } - log_switching--; -} - -static void -vlog(unsigned int cat, const char *msg, va_list args) -{ - time_t tim = time(NULL); - struct tm *tm = localtime(&tim); + struct timeval tv; + struct tm tm; byte *buf, *p; int buflen = 256; int l, l0, r; + va_list args2; - log_switch(tm); + gettimeofday(&tv, NULL); + if (!localtime_r(&tv.tv_sec, &tm)) + bzero(&tm, sizeof(tm)); + + if (log_switch_hook) + log_switch_hook(&tm); while (1) { p = buf = alloca(buflen); *p++ = cat; - p += strftime(p, buflen, " %Y-%m-%d %H:%M:%S ", tm); - if (log_progname[0]) + /* We cannot use strftime() here, because it's not re-entrant */ + p += sprintf(p, " %4d-%02d-%02d %02d:%02d:%02d", tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec); + if (log_precise_timings) + p += sprintf(p, ".%06d", (int)tv.tv_usec); + *p++ = ' '; + if (log_title) { if (log_pid) - p += sprintf(p, "[%s (%d)] ", log_progname, log_pid); + p += sprintf(p, "[%s (%d)] ", log_title, log_pid); else - p += sprintf(p, "[%s] ", log_progname); + p += sprintf(p, "[%s] ", log_title); } else { @@ -86,7 +65,9 @@ vlog(unsigned int cat, const char *msg, va_list args) } l0 = p - buf + 1; r = buflen - l0; - l = vsnprintf(p, r, msg, args); + va_copy(args2, args); + l = vsnprintf(p, r, fmt, args2); + va_end(args2); if (l < 0) l = r; else if (l < r) @@ -106,23 +87,25 @@ vlog(unsigned int cat, const char *msg, va_list args) } void -log_msg(unsigned int cat, const char *msg, ...) +msg(unsigned int cat, const char *fmt, ...) { va_list args; - va_start(args, msg); - vlog(cat, msg, args); + va_start(args, fmt); + vmsg(cat, fmt, args); va_end(args); } void -die(byte *msg, ...) +die(const char *fmt, ...) { va_list args; - va_start(args, msg); - vlog(L_FATAL, msg, args); + va_start(args, fmt); + vmsg(L_FATAL, fmt, args); va_end(args); + if (log_die_hook) + log_die_hook(); #ifdef DEBUG_DIE_BY_ABORT abort(); #else @@ -130,61 +113,37 @@ die(byte *msg, ...) #endif } -#ifdef DEBUG void -assert_failed(char *assertion, char *file, int line) +assert_failed(const char *assertion, const char *file, int line) { - log(L_FATAL, "Assertion `%s' failed at %s:%d", assertion, file, line); + msg(L_FATAL, "Assertion `%s' failed at %s:%d", assertion, file, line); abort(); } -#else + void -assert_failed(void) +assert_failed_noinfo(void) { die("Internal error: Assertion failed."); } -#endif -static byte * -log_basename(byte *n) +static const char * +log_basename(const char *n) { - byte *p = n; + const char *p = n; while (*n) - if (*n++ == '/') - p = n; + if (*n++ == '/') + p = n; return p; } void -log_init(byte *argv0) +log_init(const char *argv0) { if (argv0) { strncpy(log_progname, log_basename(argv0), sizeof(log_progname)-1); log_progname[sizeof(log_progname)-1] = 0; - } -} - -void -log_file(byte *name) -{ - if (name) - { - time_t tim = time(NULL); - struct tm *tm = localtime(&tim); - if (log_name_patt) - xfree(log_name_patt); - if (log_name) - { - xfree(log_name); - log_name = NULL; - } - log_name_patt = stralloc(name); - log_params = !!strchr(name, '%'); - log_name_size = strlen(name) + 64; /* 63 is an upper bound on expansion of % escapes */ - log_name = xmalloc(log_name_size); - log_name[0] = 0; - log_switch(tm); + log_title = log_progname; } }