X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Flog.c;h=67a3e1b843bc41272f1420530557c1ce6ea786ee;hp=9fffc1dbc00ba2123cae35afbf3d4eb0156865eb;hb=877d54e9b09e093c2102f519a84e2a52637ae035;hpb=d7832d2c6e0ef5f2839a2296c1cc2fc85c7d9632 diff --git a/src/shared/log.c b/src/shared/log.c index 9fffc1dbc..67a3e1b84 100644 --- a/src/shared/log.c +++ b/src/shared/log.c @@ -6,16 +6,16 @@ Copyright 2010 Lennart Poettering systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. systemd is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. + Lesser General Public License for more details. - You should have received a copy of the GNU General Public License + You should have received a copy of the GNU Lesser General Public License along with systemd; If not, see . ***/ @@ -240,7 +240,7 @@ int log_open(void) { return 0; } - if (log_target != LOG_TARGET_AUTO || + if ((log_target != LOG_TARGET_AUTO && log_target != LOG_TARGET_SAFE) || getpid() == 1 || isatty(STDERR_FILENO) <= 0) { @@ -266,6 +266,7 @@ int log_open(void) { } if (log_target == LOG_TARGET_AUTO || + log_target == LOG_TARGET_SAFE || log_target == LOG_TARGET_JOURNAL_OR_KMSG || log_target == LOG_TARGET_SYSLOG_OR_KMSG || log_target == LOG_TARGET_KMSG) { @@ -466,12 +467,14 @@ static int write_to_journal( "CODE_FILE=%s\n" "CODE_LINE=%i\n" "CODE_FUNCTION=%s\n" + "SYSLOG_IDENTIFIER=%s\n" "MESSAGE=", LOG_PRI(level), LOG_FAC(level), file, line, - func); + func, + program_invocation_short_name); char_array_0(header); @@ -545,7 +548,9 @@ static int log_dispatch( if (k <= 0 && (log_target == LOG_TARGET_AUTO || + log_target == LOG_TARGET_SAFE || log_target == LOG_TARGET_SYSLOG_OR_KMSG || + log_target == LOG_TARGET_JOURNAL_OR_KMSG || log_target == LOG_TARGET_KMSG)) { k = write_to_kmsg(level, file, line, func, buffer); @@ -653,6 +658,127 @@ _noreturn_ void log_assert_failed_unreachable(const char *text, const char *file log_assert(text, file, line, func, "Code should not be reached '%s' at %s:%u, function %s(). Aborting."); } +int log_oom_internal(const char *file, int line, const char *func) { + log_meta(LOG_ERR, file, line, func, "Out of memory."); + return -ENOMEM; +} + +int log_struct_internal( + int level, + const char *file, + int line, + const char *func, + const char *format, ...) { + + int saved_errno; + va_list ap; + int r; + + if (_likely_(LOG_PRI(level) > log_max_level)) + return 0; + + if (log_target == LOG_TARGET_NULL) + return 0; + + if ((level & LOG_FACMASK) == 0) + level = log_facility | LOG_PRI(level); + + saved_errno = errno; + + if ((log_target == LOG_TARGET_AUTO || + log_target == LOG_TARGET_JOURNAL_OR_KMSG || + log_target == LOG_TARGET_JOURNAL) && + journal_fd >= 0) { + + char header[LINE_MAX]; + struct iovec iovec[17]; + unsigned n = 0, i; + struct msghdr mh; + const char nl = '\n'; + + /* If the journal is available do structured logging */ + + snprintf(header, sizeof(header), + "PRIORITY=%i\n" + "SYSLOG_FACILITY=%i\n" + "CODE_FILE=%s\n" + "CODE_LINE=%i\n" + "CODE_FUNCTION=%s\n" + "SYSLOG_IDENTIFIER=%s\n", + LOG_PRI(level), + LOG_FAC(level), + file, + line, + func, + program_invocation_short_name); + char_array_0(header); + + zero(iovec); + IOVEC_SET_STRING(iovec[n++], header); + + va_start(ap, format); + while (format && n + 1 < ELEMENTSOF(iovec)) { + char *buf; + + if (vasprintf(&buf, format, ap) < 0) { + r = -ENOMEM; + goto finish; + } + + IOVEC_SET_STRING(iovec[n++], buf); + + iovec[n].iov_base = (char*) &nl; + iovec[n].iov_len = 1; + n++; + + format = va_arg(ap, char *); + } + va_end(ap); + + zero(mh); + mh.msg_iov = iovec; + mh.msg_iovlen = n; + + if (sendmsg(journal_fd, &mh, MSG_NOSIGNAL) < 0) + r = -errno; + else + r = 1; + + finish: + for (i = 1; i < n; i += 2) + free(iovec[i].iov_base); + + } else { + char buf[LINE_MAX]; + bool found = false; + + /* Fallback if journal logging is not available */ + + va_start(ap, format); + while (format) { + + vsnprintf(buf, sizeof(buf), format, ap); + char_array_0(buf); + + if (startswith(buf, "MESSAGE=")) { + found = true; + break; + } + + format = va_arg(ap, char *); + } + va_end(ap); + + if (found) + r = log_dispatch(level, file, line, func, buf + 8); + else + r = -EINVAL; + } + + errno = saved_errno; + return r; +} + int log_set_target_from_string(const char *e) { LogTarget t; @@ -678,21 +804,21 @@ int log_set_max_level_from_string(const char *e) { void log_parse_environment(void) { const char *e; - if ((e = getenv("SYSTEMD_LOG_TARGET"))) - if (log_set_target_from_string(e) < 0) - log_warning("Failed to parse log target %s. Ignoring.", e); + e = __secure_getenv("SYSTEMD_LOG_TARGET"); + if (e && log_set_target_from_string(e) < 0) + log_warning("Failed to parse log target %s. Ignoring.", e); - if ((e = getenv("SYSTEMD_LOG_LEVEL"))) - if (log_set_max_level_from_string(e) < 0) - log_warning("Failed to parse log level %s. Ignoring.", e); + e = __secure_getenv("SYSTEMD_LOG_LEVEL"); + if (e && log_set_max_level_from_string(e) < 0) + log_warning("Failed to parse log level %s. Ignoring.", e); - if ((e = getenv("SYSTEMD_LOG_COLOR"))) - if (log_show_color_from_string(e) < 0) - log_warning("Failed to parse bool %s. Ignoring.", e); + e = __secure_getenv("SYSTEMD_LOG_COLOR"); + if (e && log_show_color_from_string(e) < 0) + log_warning("Failed to parse bool %s. Ignoring.", e); - if ((e = getenv("SYSTEMD_LOG_LOCATION"))) - if (log_show_location_from_string(e) < 0) - log_warning("Failed to parse bool %s. Ignoring.", e); + e = __secure_getenv("SYSTEMD_LOG_LOCATION"); + if (e && log_show_location_from_string(e) < 0) + log_warning("Failed to parse bool %s. Ignoring.", e); } LogTarget log_get_target(void) { @@ -741,6 +867,7 @@ static const char *const log_target_table[] = { [LOG_TARGET_SYSLOG] = "syslog", [LOG_TARGET_SYSLOG_OR_KMSG] = "syslog-or-kmsg", [LOG_TARGET_AUTO] = "auto", + [LOG_TARGET_SAFE] = "safe", [LOG_TARGET_NULL] = "null" };