X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flog.c;h=9fffc1dbc00ba2123cae35afbf3d4eb0156865eb;hp=6caa5fad0b8c37bb6809948f9c0aab343164d287;hb=1c0f62e37b0e775df7cb6121bc6ae64d1d885d3b;hpb=5ba081b0fb02380cee4c2ff5bc7e05f869eb8415 diff --git a/src/log.c b/src/log.c index 6caa5fad0..9fffc1dbc 100644 --- a/src/log.c +++ b/src/log.c @@ -33,10 +33,11 @@ #include "macro.h" #include "socket-util.h" -#define SOCKET_TIMEOUT_USEC (5*USEC_PER_SEC) +#define SNDBUF_SIZE (8*1024*1024) static LogTarget log_target = LOG_TARGET_CONSOLE; static int log_max_level = LOG_INFO; +static int log_facility = LOG_DAEMON; static int console_fd = STDERR_FILENO; static int syslog_fd = -1; @@ -120,24 +121,16 @@ void log_close_syslog(void) { } static int create_log_socket(int type) { - struct timeval tv; int fd; - if (getpid() == 1) - /* systemd should not block on syslog */ - type |= SOCK_NONBLOCK; + /* All output to the syslog/journal fds we do asynchronously, + * and if the buffers are full we just drop the messages */ - fd = socket(AF_UNIX, type|SOCK_CLOEXEC, 0); + fd = socket(AF_UNIX, type|SOCK_CLOEXEC|SOCK_NONBLOCK, 0); if (fd < 0) return -errno; - /* Make sure we don't block for more than 5s when talking to - * syslog */ - timeval_store(&tv, SOCKET_TIMEOUT_USEC); - if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) < 0) { - close_nointr_nofail(fd); - return -errno; - } + fd_inc_sndbuf(fd, SNDBUF_SIZE); return fd; } @@ -159,7 +152,7 @@ static int log_open_syslog(void) { goto fail; } - if (connect(syslog_fd, &sa.sa, sizeof(sa)) < 0) { + if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) { close_nointr_nofail(syslog_fd); /* Some legacy syslog systems still use stream @@ -171,7 +164,7 @@ static int log_open_syslog(void) { goto fail; } - if (connect(syslog_fd, &sa.sa, sizeof(sa)) < 0) { + if (connect(syslog_fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) { r = -errno; goto fail; } @@ -318,6 +311,10 @@ void log_set_max_level(int level) { log_max_level = level; } +void log_set_facility(int facility) { + log_facility = facility; +} + static int write_to_console( int level, const char*file, @@ -344,7 +341,7 @@ static int write_to_console( } if (highlight) - IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_ON); + IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_RED_ON); IOVEC_SET_STRING(iovec[n++], buffer); if (highlight) IOVEC_SET_STRING(iovec[n++], ANSI_HIGHLIGHT_OFF); @@ -465,11 +462,13 @@ static int write_to_journal( snprintf(header, sizeof(header), "PRIORITY=%i\n" + "SYSLOG_FACILITY=%i\n" "CODE_FILE=%s\n" "CODE_LINE=%i\n" "CODE_FUNCTION=%s\n" "MESSAGE=", LOG_PRI(level), + LOG_FAC(level), file, line, func); @@ -505,7 +504,7 @@ static int log_dispatch( /* Patch in LOG_DAEMON facility if necessary */ if ((level & LOG_FACMASK) == 0) - level = LOG_DAEMON | LOG_PRI(level); + level = log_facility | LOG_PRI(level); do { char *e; @@ -590,26 +589,22 @@ int log_dump_internal( return r; } -int log_meta( +int log_metav( int level, const char*file, int line, const char *func, - const char *format, ...) { + const char *format, + va_list ap) { char buffer[LINE_MAX]; int saved_errno, r; - va_list ap; if (_likely_(LOG_PRI(level) > log_max_level)) return 0; saved_errno = errno; - - va_start(ap, format); vsnprintf(buffer, sizeof(buffer), format, ap); - va_end(ap); - char_array_0(buffer); r = log_dispatch(level, file, line, func, buffer); @@ -618,28 +613,44 @@ int log_meta( return r; } -void log_assert( +int log_meta( + int level, const char*file, int line, const char *func, const char *format, ...) { - static char buffer[LINE_MAX]; - int saved_errno = errno; + int r; va_list ap; va_start(ap, format); - vsnprintf(buffer, sizeof(buffer), format, ap); + r = log_metav(level, file, line, func, format, ap); va_end(ap); + return r; +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wformat-nonliteral" +_noreturn_ static void log_assert(const char *text, const char *file, int line, const char *func, const char *format) { + static char buffer[LINE_MAX]; + + snprintf(buffer, sizeof(buffer), format, text, file, line, func); + char_array_0(buffer); log_abort_msg = buffer; log_dispatch(LOG_CRIT, file, line, func, buffer); abort(); +} +#pragma GCC diagnostic pop - /* If the user chose to ignore this SIGABRT, we are happy to go on, as if nothing happened. */ - errno = saved_errno; +_noreturn_ void log_assert_failed(const char *text, const char *file, int line, const char *func) { + log_assert(text, file, line, func, "Assertion '%s' failed at %s:%u, function %s(). Aborting."); +} + +_noreturn_ void log_assert_failed_unreachable(const char *text, const char *file, int line, const char *func) { + log_assert(text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting."); } int log_set_target_from_string(const char *e) {