X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=log.c;h=e1c9ed7471611a30699b8f1b567372238ee2e136;hp=497433a8b01751929dcbc06f42cf63aa152df9ef;hb=2a1a539789190c2d413710bcd88f1e351400d700;hpb=c9b80453525f2a1ec3c71f7b0f649f786ec9e8dd diff --git a/log.c b/log.c index 497433a8b..e1c9ed747 100644 --- a/log.c +++ b/log.c @@ -40,10 +40,14 @@ static int log_max_level = LOG_DEBUG; static int syslog_fd = -1; static int kmsg_fd = -1; +/* Akin to glibc's __abort_msg; which is private and we hance cannot + * use here. */ +static char *log_abort_msg = NULL; + void log_close_kmsg(void) { if (kmsg_fd >= 0) { - close_nointr(kmsg_fd); + close_nointr_nofail(kmsg_fd); kmsg_fd = -1; } } @@ -71,7 +75,7 @@ int log_open_kmsg(void) { void log_close_syslog(void) { if (syslog_fd >= 0) { - close_nointr(syslog_fd); + close_nointr_nofail(syslog_fd); syslog_fd = -1; } } @@ -245,6 +249,26 @@ static int write_to_kmsg( return 0; } +#define LOG_DISPATCH(level,file,line,func,format) \ + do { \ + va_list _ap; \ + bool written = false; \ + if (log_target == LOG_TARGET_KMSG) { \ + va_start(_ap, format); \ + written = write_to_kmsg(level, file, line, func, format, _ap) >= 0; \ + va_end(_ap); \ + } else if (log_target == LOG_TARGET_SYSLOG) { \ + va_start(_ap, format); \ + written = write_to_syslog(level, file, line, func, format, _ap) >= 0; \ + va_end(_ap); \ + } \ + if (!written) { \ + va_start(_ap, format); \ + write_to_console(level, file, line, func, format, _ap); \ + va_end(_ap); \ + } \ + } while (false) + void log_meta( int level, const char*file, @@ -252,32 +276,37 @@ void log_meta( const char *func, const char *format, ...) { - va_list ap; - bool written; int saved_errno; - if (LOG_PRI(level) > log_max_level) + if (_likely(LOG_PRI(level) > log_max_level)) return; saved_errno = errno; - written = false; - - if (log_target == LOG_TARGET_KMSG) { - va_start(ap, format); - written = write_to_kmsg(level, file, line, func, format, ap) >= 0; - va_end(ap); - } else if (log_target == LOG_TARGET_SYSLOG) { - va_start(ap, format); - written = write_to_syslog(level, file, line, func, format, ap) >= 0; - va_end(ap); - } + LOG_DISPATCH(level, file, line, func, format); + errno = saved_errno; +} - if (!written) { - va_start(ap, format); - write_to_console(level, file, line, func, format, ap); - va_end(ap); - } +void log_assert( + const char*file, + int line, + const char *func, + const char *format, ...) { + static char buffer[LOG_BUFFER_MAX]; + va_list ap; + int saved_errno = errno; + + va_start(ap, format); + vsnprintf(buffer, sizeof(buffer), format, ap); + va_end(ap); + + char_array_0(buffer); + log_abort_msg = buffer; + + LOG_DISPATCH(LOG_CRIT, file, line, func, format); + abort(); + + /* If the user chose to ignore this SIGABRT, we are happy to go on, as if nothing happened. */ errno = saved_errno; } @@ -313,6 +342,14 @@ void log_parse_environment(void) { log_warning("Failed to parse log level %s. Ignoring.", e); } +LogTarget log_get_target(void) { + return log_target; +} + +int log_get_max_level(void) { + return log_max_level; +} + static const char *const log_target_table[] = { [LOG_TARGET_CONSOLE] = "console", [LOG_TARGET_SYSLOG] = "syslog",