X-Git-Url: https://git.distorted.org.uk/~mdw/disorder/blobdiff_plain/cca89d7ce589d10a226c6dfa212e36cbcad25fd2..73df7db645fa36e1e6d732ec34b7020bc316248e:/lib/log.c diff --git a/lib/log.c b/lib/log.c index 988a845..88657a9 100644 --- a/lib/log.c +++ b/lib/log.c @@ -138,8 +138,10 @@ static void logfp(int pri, const char *msg, void *user) { if(logdate) { char timebuf[64]; struct tm *tm; + time_t t; gettimeofday(&tv, 0); - tm = localtime(&tv.tv_sec); + t = tv.tv_sec; + tm = localtime(&t); strftime(timebuf, sizeof timebuf, "%Y-%m-%d %H:%M:%S %Z", tm); fprintf(fp, "%s: ", timebuf); } @@ -165,6 +167,7 @@ static void logfp(int pri, const char *msg, void *user) { } fputs(msg, fp); fputc('\n', fp); + fflush(fp); } #if HAVE_SYSLOG_H @@ -205,12 +208,14 @@ static void logger(int pri, const char *fmt, ...) { /** @brief Format and log a message * @param pri Message priority (as per syslog) + * @param ec Error class * @param fmt Format string * @param errno_value Errno value to include as a string, or 0 * @param ap Argument list */ -void elog(int pri, int errno_value, const char *fmt, va_list ap) { +void elog(int pri, enum error_class ec, int errno_value, const char *fmt, va_list ap) { char buffer[1024]; + char errbuf[1024]; if(errno_value == 0) vlogger(pri, fmt, ap); @@ -218,7 +223,8 @@ void elog(int pri, int errno_value, const char *fmt, va_list ap) { memset(buffer, 0, sizeof buffer); byte_vsnprintf(buffer, sizeof buffer, fmt, ap); buffer[sizeof buffer - 1] = 0; - logger(pri, "%s: %s", buffer, strerror(errno_value)); + logger(pri, "%s: %s", buffer, + format_error(ec, errno_value, errbuf, sizeof errbuf)); } } @@ -231,7 +237,22 @@ void disorder_fatal(int errno_value, const char *msg, ...) { va_list ap; va_start(ap, msg); - elog(LOG_CRIT, errno_value, msg, ap); + elog(LOG_CRIT, ec_errno, errno_value, msg, ap); + va_end(ap); + if(getenv("DISORDER_FATAL_ABORT")) abort(); + exitfn(EXIT_FAILURE); +} + +/** @brief Log an error and quit + * + * If @c ${DISORDER_FATAL_ABORT} is defined (as anything) then the process + * is aborted, so you can get a backtrace. + */ +void disorder_fatal_ec(enum error_class ec, int errno_value, const char *msg, ...) { + va_list ap; + + va_start(ap, msg); + elog(LOG_CRIT, ec, errno_value, msg, ap); va_end(ap); if(getenv("DISORDER_FATAL_ABORT")) abort(); exitfn(EXIT_FAILURE); @@ -242,7 +263,16 @@ void disorder_error(int errno_value, const char *msg, ...) { va_list ap; va_start(ap, msg); - elog(LOG_ERR, errno_value, msg, ap); + elog(LOG_ERR, ec_errno, errno_value, msg, ap); + va_end(ap); +} + +/** @brief Log an error */ +void disorder_error_ec(enum error_class ec, int errno_value, const char *msg, ...) { + va_list ap; + + va_start(ap, msg); + elog(LOG_ERR, ec, errno_value, msg, ap); va_end(ap); } @@ -251,7 +281,7 @@ void disorder_info(const char *msg, ...) { va_list ap; va_start(ap, msg); - elog(LOG_INFO, 0, msg, ap); + elog(LOG_INFO, ec_none, 0, msg, ap); va_end(ap); } @@ -272,6 +302,54 @@ void set_progname(char **argv) { progname = argv[0]; } +/** @brief Format an error string + * @param ec Error class + * @param err Error code (interpretation defined by @p ec) + * @param buffer Output buffer + * @param bufsize Size of output buffer + * @return Pointer to error string + * + * The return value may or may not be @p buffer. + */ +#if !_WIN32 +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif +const char *format_error(enum error_class ec, int err, char buffer[], size_t bufsize) { +#if _WIN32 + size_t n; + switch(ec) { + default: + if(!FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + buffer, + bufsize, + NULL)) + disorder_fatal(0, "FormatMessage failed"); + n = strlen(buffer); + while(n > 0 && isspace((unsigned char)buffer[n-1])) + --n; + buffer[n] = 0; + return buffer; + case ec_errno: + strerror_s(buffer, bufsize, err); + return buffer; + case ec_none: + return "(none)"; + } +#else + switch(ec) { + default: + return strerror(err); + case ec_getaddrinfo: + return gai_strerror(err); + case ec_none: + return "(none)"; + } +#endif +} + /* Local Variables: c-basic-offset:2