chiark / gitweb /
systemctl: don't show cgroup field for a unit if cgroup is empty
[elogind.git] / src / shared / log.c
index 67a3e1b843bc41272f1420530557c1ce6ea786ee..63578683ab6575b73df32ddd9164893471d5f186 100644 (file)
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <stddef.h>
+#include <printf.h>
 
 #include "log.h"
 #include "util.h"
+#include "missing.h"
 #include "macro.h"
 #include "socket-util.h"
 
@@ -72,14 +74,9 @@ static int log_open_console(void) {
                 return 0;
 
         if (getpid() == 1) {
-
                 console_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
-                if (console_fd < 0) {
-                        log_error("Failed to open /dev/console for logging: %s", strerror(-console_fd));
+                if (console_fd < 0)
                         return console_fd;
-                }
-
-                log_debug("Successfully opened /dev/console for logging.");
         } else
                 console_fd = STDERR_FILENO;
 
@@ -101,12 +98,8 @@ static int log_open_kmsg(void) {
                 return 0;
 
         kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC);
-        if (kmsg_fd < 0) {
-                log_error("Failed to open /dev/kmsg for logging: %s", strerror(errno));
+        if (kmsg_fd < 0)
                 return -errno;
-        }
-
-        log_debug("Successfully opened /dev/kmsg for logging.");
 
         return 0;
 }
@@ -173,13 +166,10 @@ static int log_open_syslog(void) {
         } else
                 syslog_is_stream = false;
 
-        log_debug("Successfully opened syslog for logging.");
-
         return 0;
 
 fail:
         log_close_syslog();
-        log_debug("Failed to open syslog for logging: %s", strerror(-r));
         return r;
 }
 
@@ -214,13 +204,10 @@ static int log_open_journal(void) {
                 goto fail;
         }
 
-        log_debug("Successfully opened journal for logging.");
-
         return 0;
 
 fail:
         log_close_journal();
-        log_debug("Failed to open journal for logging: %s", strerror(-r));
         return r;
 }
 
@@ -719,11 +706,23 @@ int log_struct_internal(
                 va_start(ap, format);
                 while (format && n + 1 < ELEMENTSOF(iovec)) {
                         char *buf;
+                        va_list aq;
 
-                        if (vasprintf(&buf, format, ap) < 0) {
+                        /* We need to copy the va_list structure,
+                         * since vasprintf() leaves it afterwards at
+                         * an undefined location */
+
+                        va_copy(aq, ap);
+                        if (vasprintf(&buf, format, aq) < 0) {
+                                va_end(aq);
                                 r = -ENOMEM;
                                 goto finish;
                         }
+                        va_end(aq);
+
+                        /* Now, jump enough ahead, so that we point to
+                         * the next format string */
+                        VA_FORMAT_ADVANCE(format, ap);
 
                         IOVEC_SET_STRING(iovec[n++], buf);
 
@@ -733,7 +732,6 @@ int log_struct_internal(
 
                         format = va_arg(ap, char *);
                 }
-                va_end(ap);
 
                 zero(mh);
                 mh.msg_iov = iovec;
@@ -745,6 +743,7 @@ int log_struct_internal(
                         r = 1;
 
         finish:
+                va_end(ap);
                 for (i = 1; i < n; i += 2)
                         free(iovec[i].iov_base);
 
@@ -756,8 +755,11 @@ int log_struct_internal(
 
                 va_start(ap, format);
                 while (format) {
+                        va_list aq;
 
-                        vsnprintf(buf, sizeof(buf), format, ap);
+                        va_copy(aq, ap);
+                        vsnprintf(buf, sizeof(buf), format, aq);
+                        va_end(aq);
                         char_array_0(buf);
 
                         if (startswith(buf, "MESSAGE=")) {
@@ -765,6 +767,8 @@ int log_struct_internal(
                                 break;
                         }
 
+                        VA_FORMAT_ADVANCE(format, ap);
+
                         format = va_arg(ap, char *);
                 }
                 va_end(ap);
@@ -804,19 +808,19 @@ int log_set_max_level_from_string(const char *e) {
 void log_parse_environment(void) {
         const char *e;
 
-        e = __secure_getenv("SYSTEMD_LOG_TARGET");
+        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);
 
-        e = __secure_getenv("SYSTEMD_LOG_LEVEL");
+        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);
 
-        e = __secure_getenv("SYSTEMD_LOG_COLOR");
+        e = secure_getenv("SYSTEMD_LOG_COLOR");
         if (e && log_show_color_from_string(e) < 0)
                 log_warning("Failed to parse bool %s. Ignoring.", e);
 
-        e = __secure_getenv("SYSTEMD_LOG_LOCATION");
+        e = secure_getenv("SYSTEMD_LOG_LOCATION");
         if (e && log_show_location_from_string(e) < 0)
                 log_warning("Failed to parse bool %s. Ignoring.", e);
 }
@@ -859,6 +863,13 @@ int log_show_location_from_string(const char *e) {
         return 0;
 }
 
+bool log_on_console(void) {
+        if (log_target == LOG_TARGET_CONSOLE)
+                return true;
+
+        return syslog_fd < 0 && kmsg_fd < 0 && journal_fd < 0;
+}
+
 static const char *const log_target_table[] = {
         [LOG_TARGET_CONSOLE] = "console",
         [LOG_TARGET_KMSG] = "kmsg",