X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=lib%2Flog.c;h=713fa768c0c6acb91806d52319d4802d52d05962;hb=78775c3f5e38e8bee7d04b0f994766c7dd1e6578;hp=4d81e85d36d7d068e50bd0f345461a9a845e5fda;hpb=3c6ffef681f366214fdc970488e21aa89caab992;p=libucw.git diff --git a/lib/log.c b/lib/log.c index 4d81e85d..713fa768 100644 --- a/lib/log.c +++ b/lib/log.c @@ -1,83 +1,139 @@ /* - * Sherlock Library -- Logging + * UCW Library -- Logging * - * (c) 1997--2001 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. */ #include "lib/lib.h" #include #include -#include -#include +#include #include #include +#include +#include -static char *log_progname; -static pid_t log_pid; +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) +vlog_msg(unsigned int cat, const char *msg, va_list args) { - log_pid = getpid(); -} + struct timeval tv; + struct tm tm; + byte *buf, *p; + int buflen = 256; + int l, l0, r; + va_list args2; -static void -vlog(unsigned int cat, const char *msg, va_list args) -{ - time_t tim = time(NULL); - struct tm *tm = localtime(&tim); - char *prog = log_progname ?: "?"; - char buf[32]; + gettimeofday(&tv, NULL); + if (!localtime_r(&tv.tv_sec, &tm)) + bzero(&tm, sizeof(tm)); - strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", tm); - fprintf(stderr, "%c %s ", cat, buf); - if (log_progname) + if (log_switch_hook) + log_switch_hook(&tm); + while (1) { - if (log_pid) - fprintf(stderr, "[%s (%d)] ", log_progname, log_pid); + p = buf = alloca(buflen); + *p++ = cat; + /* 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_title, log_pid); + else + p += sprintf(p, "[%s] ", log_title); + } else - fprintf(stderr, "[%s] ", log_progname); - } - else - { - if (log_pid) - fprintf(stderr, "[%d] ", log_pid); + { + if (log_pid) + p += sprintf(p, "[%d] ", log_pid); + } + l0 = p - buf + 1; + r = buflen - l0; + va_copy(args2, args); + l = vsnprintf(p, r, msg, args2); + va_end(args2); + if (l < 0) + l = r; + else if (l < r) + { + while (*p) + { + if (*p < 0x20 && *p != '\t') + *p = 0x7f; + p++; + } + *p = '\n'; + write(2, buf, l + l0); + return; + } + buflen = l + l0 + 1; } - vfprintf(stderr, msg, args); - fputc('\n', stderr); - fflush(stderr); } void -log(unsigned int cat, const char *msg, ...) +log_msg(unsigned int cat, const char *msg, ...) { va_list args; va_start(args, msg); - vlog(cat, msg, args); + vlog_msg(cat, msg, args); va_end(args); } void -die(byte *msg, ...) +die(const char *msg, ...) { va_list args; va_start(args, msg); - vlog(L_FATAL, msg, args); + vlog_msg(L_FATAL, msg, args); va_end(args); + if (log_die_hook) + log_die_hook(); +#ifdef DEBUG_DIE_BY_ABORT + abort(); +#else exit(1); +#endif +} + +void +assert_failed(char *assertion, char *file, int line) +{ + log(L_FATAL, "Assertion `%s' failed at %s:%d", assertion, file, line); + abort(); +} + +void +assert_failed_noinfo(void) +{ + die("Internal error: Assertion failed."); } static byte * -basename(byte *n) +log_basename(byte *n) { byte *p = n; while (*n) - if (*n++ == '/') - p = n; + if (*n++ == '/') + p = n; return p; } @@ -85,19 +141,9 @@ void log_init(byte *argv0) { if (argv0) - log_progname = basename(argv0); -} - -void -log_file(byte *name) -{ - if (name) { - int 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); + strncpy(log_progname, log_basename(argv0), sizeof(log_progname)-1); + log_progname[sizeof(log_progname)-1] = 0; + log_title = log_progname; } }