diff options
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | man/sd_journal_print.xml | 29 | ||||
-rw-r--r-- | man/systemd.journal-fields.xml | 13 | ||||
-rw-r--r-- | src/journal/journal-send.c | 91 | ||||
-rw-r--r-- | src/journal/libsystemd-journal.sym | 2 | ||||
-rw-r--r-- | src/journal/test-journal-send.c | 5 | ||||
-rw-r--r-- | src/systemd/sd-journal.h | 3 |
8 files changed, 140 insertions, 6 deletions
diff --git a/Makefile.am b/Makefile.am index cf37ebe627..77aed920a5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -557,6 +557,7 @@ MANPAGES_ALIAS = \ man/sd_journal_printv.3 \ man/sd_journal_send.3 \ man/sd_journal_sendv.3 \ + man/sd_journal_perror.3 \ man/SD_JOURNAL_SUPPRESS_LOCATION.3 \ man/sd_journal_open_directory.3 \ man/sd_journal_close.3 \ @@ -624,6 +625,7 @@ man/sd_id128_get_boot.3: man/sd_id128_get_machine.3 man/sd_journal_printv.3: man/sd_journal_print.3 man/sd_journal_send.3: man/sd_journal_print.3 man/sd_journal_sendv.3: man/sd_journal_print.3 +man/sd_journal_perror.3: man/sd_journal_print.3 man/SD_JOURNAL_SUPPRESS_LOCATION.3: man/sd_journal_print.3 man/sd_journal_open_directory.3: man/sd_journal_open.3 man/sd_journal_close.3: man/sd_journal_open.3 diff --git a/configure.ac b/configure.ac index cef2539e27..5145298204 100644 --- a/configure.ac +++ b/configure.ac @@ -89,7 +89,6 @@ CC_CHECK_FLAGS_APPEND([with_cflags], [CFLAGS], [\ -W \ -Wextra \ -Wno-inline \ - -Wvla \ -Wundef \ -Wformat=2 \ -Wlogical-op \ diff --git a/man/sd_journal_print.xml b/man/sd_journal_print.xml index dfe99192e7..7eac6c8192 100644 --- a/man/sd_journal_print.xml +++ b/man/sd_journal_print.xml @@ -47,6 +47,7 @@ <refname>sd_journal_printv</refname> <refname>sd_journal_send</refname> <refname>sd_journal_sendv</refname> + <refname>sd_journal_perror</refname> <refname>SD_JOURNAL_SUPPRESS_LOCATION</refname> <refpurpose>Submit log entries to the journal</refpurpose> </refnamediv> @@ -81,6 +82,11 @@ <paramdef>int <parameter>n</parameter></paramdef> </funcprototype> + <funcprototype> + <funcdef>int <function>sd_journal_perror</function></funcdef> + <paramdef>const char* <parameter>message</parameter></paramdef> + </funcprototype> + </funcsynopsis> </refsynopsisdiv> @@ -150,6 +156,21 @@ particularly useful to submit binary objects to the journal where that is necessary.</para> + <para><function>sd_journal_perror()</function> is a + similar to + <citerefentry><refentrytitle>perror</refentrytitle><manvolnum>3</manvolnum></citerefentry> + and writes a message to the journal that consists of + the passed string, suffixed with ": " and a human + readable representation of the current error code + stored in + <citerefentry><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry>. If + the message string is passed as NULL or empty string + only the error string representation will be written, + prefixed with nothing. An additional journal field + ERRNO= is included in the entry containing the numeric + error code formatted as decimal string. The log + priority used is <literal>LOG_ERR</literal> (3).</para> + <para>Note that <function>sd_journal_send()</function> is a wrapper around <function>sd_journal_sendv()</function> to make it @@ -191,8 +212,10 @@ sd_journal_send("MESSAGE=Hello World, this is PID %lu!", (unsigned long) getpid( <refsect1> <title>Return Value</title> - <para>The four calls return 0 on success or a - negative errno-style error code.</para> + <para>The four calls return 0 on success or a negative + errno-style error code. The + <citerefentry><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry> + variable itself is not altered.</para> </refsect1> <refsect1> @@ -217,6 +240,8 @@ sd_journal_send("MESSAGE=Hello World, this is PID %lu!", (unsigned long) getpid( <citerefentry><refentrytitle>sd-journal</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>sd_journal_stream_fd</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>perror</refentrytitle><manvolnum>3</manvolnum></citerefentry>, + <citerefentry><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry>, <citerefentry><refentrytitle>systemd.journal-fields</refentrytitle><manvolnum>7</manvolnum></citerefentry> </para> </refsect1> diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml index 6a9fd9d85c..59bb8ad70a 100644 --- a/man/systemd.journal-fields.xml +++ b/man/systemd.journal-fields.xml @@ -133,6 +133,19 @@ </varlistentry> <varlistentry> + <term>ERRNO=</term> + <listitem> + <para>The low-level Unix error + number causing this entry, if + any. Contains the numeric + value of + <citerefentry><refentrytitle>errno</refentrytitle><manvolnum>3</manvolnum></citerefentry> + formatted as decimal + string.</para> + </listitem> + </varlistentry> + + <varlistentry> <term>SYSLOG_FACILITY=</term> <term>SYSLOG_IDENTIFIER=</term> <term>SYSLOG_PID=</term> diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c index bc44828e1c..d0f3b725ff 100644 --- a/src/journal/journal-send.c +++ b/src/journal/journal-send.c @@ -73,8 +73,11 @@ _public_ int sd_journal_print(int priority, const char *format, ...) { } _public_ int sd_journal_printv(int priority, const char *format, va_list ap) { - char buffer[8 + LINE_MAX], p[11]; - struct iovec iov[2]; + + /* FIXME: Instead of limiting things to LINE_MAX we could do a + C99 variable-length array on the stack here in a loop. */ + + char buffer[8 + LINE_MAX], p[11]; struct iovec iov[2]; if (priority < 0 || priority > 7) return -EINVAL; @@ -340,6 +343,63 @@ finish: return r; } +static int fill_iovec_perror_and_send(const char *message, int skip, struct iovec iov[]) { + size_t n, k, r; + int saved_errno; + + saved_errno = errno; + + k = isempty(message) ? 0 : strlen(message) + 2; + n = 8 + k + 256 + 1; + + for (;;) { + char buffer[n]; + char* j; + + errno = 0; + j = strerror_r(saved_errno, buffer + 8 + k, n - 8 - k); + if (errno == 0) { + char error[6 + 10 + 1]; /* for a 32bit value */ + + if (j != buffer + 8 + k) + memmove(buffer + 8 + k, j, strlen(j)+1); + + memcpy(buffer, "MESSAGE=", 8); + + if (k > 0) { + memcpy(buffer + 8, message, k - 2); + memcpy(buffer + 8 + k - 2, ": ", 2); + } + + snprintf(error, sizeof(error), "ERRNO=%u", saved_errno); + char_array_0(error); + + IOVEC_SET_STRING(iov[skip+0], "PRIORITY=3"); + IOVEC_SET_STRING(iov[skip+1], buffer); + IOVEC_SET_STRING(iov[skip+2], error); + + r = sd_journal_sendv(iov, skip + 3); + + errno = saved_errno; + return r; + } + + if (errno != ERANGE) { + r = -errno; + errno = saved_errno; + return r; + } + + n *= 2; + } +} + +_public_ int sd_journal_perror(const char *message) { + struct iovec iovec[3]; + + return fill_iovec_perror_and_send(message, 0, iovec); +} + _public_ int sd_journal_stream_fd(const char *identifier, int priority, int level_prefix) { union sockaddr_union sa; int fd; @@ -489,7 +549,11 @@ finish: return r; } -_public_ int sd_journal_sendv_with_location(const char *file, const char *line, const char *func, const struct iovec *iov, int n) { +_public_ int sd_journal_sendv_with_location( + const char *file, const char *line, + const char *func, + const struct iovec *iov, int n) { + struct iovec *niov; char *f; size_t fl; @@ -514,3 +578,24 @@ _public_ int sd_journal_sendv_with_location(const char *file, const char *line, return sd_journal_sendv(niov, n); } + +_public_ int sd_journal_perror_with_location( + const char *file, const char *line, + const char *func, + const char *message) { + + struct iovec iov[6]; + size_t fl; + char *f; + + fl = strlen(func); + f = alloca(fl + 10); + memcpy(f, "CODE_FUNC=", 10); + memcpy(f + 10, func, fl + 1); + + IOVEC_SET_STRING(iov[0], file); + IOVEC_SET_STRING(iov[1], line); + IOVEC_SET_STRING(iov[2], f); + + return fill_iovec_perror_and_send(message, 3, iov); +} diff --git a/src/journal/libsystemd-journal.sym b/src/journal/libsystemd-journal.sym index c33474aeab..770f899333 100644 --- a/src/journal/libsystemd-journal.sym +++ b/src/journal/libsystemd-journal.sym @@ -63,4 +63,6 @@ global: sd_journal_wait; sd_journal_open_directory; sd_journal_add_disjunction; + sd_journal_perror; + sd_journal_perror_with_location; } LIBSYSTEMD_JOURNAL_184; diff --git a/src/journal/test-journal-send.c b/src/journal/test-journal-send.c index 9d376d1e56..e708fa4406 100644 --- a/src/journal/test-journal-send.c +++ b/src/journal/test-journal-send.c @@ -32,5 +32,10 @@ int main(int argc, char *argv[]) { "VALUE=%i", 7, NULL); + errno = ENOENT; + sd_journal_perror("Foobar"); + + sd_journal_perror(""); + return 0; } diff --git a/src/systemd/sd-journal.h b/src/systemd/sd-journal.h index e70f575ce9..de1c8f38f2 100644 --- a/src/systemd/sd-journal.h +++ b/src/systemd/sd-journal.h @@ -41,12 +41,14 @@ int sd_journal_print(int priority, const char *format, ...) __attribute__ ((form int sd_journal_printv(int priority, const char *format, va_list ap); int sd_journal_send(const char *format, ...) __attribute__((sentinel)); int sd_journal_sendv(const struct iovec *iov, int n); +int sd_journal_perror(const char *message); /* Used by the macros below. Don't call this directly. */ int sd_journal_print_with_location(int priority, const char *file, const char *line, const char *func, const char *format, ...) __attribute__ ((format (printf, 5, 6))); int sd_journal_printv_with_location(int priority, const char *file, const char *line, const char *func, const char *format, va_list ap); int sd_journal_send_with_location(const char *file, const char *line, const char *func, const char *format, ...) __attribute__((sentinel)); int sd_journal_sendv_with_location(const char *file, const char *line, const char *func, const struct iovec *iov, int n); +int sd_journal_perror_with_location(const char *file, const char *line, const char *func, const char *message); /* implicitly add code location to messages sent, if this is enabled */ #ifndef SD_JOURNAL_SUPPRESS_LOCATION @@ -58,6 +60,7 @@ int sd_journal_sendv_with_location(const char *file, const char *line, const cha #define sd_journal_printv(priority, format, ap) sd_journal_printv_with_location(priority, "CODE_FILE=" __FILE__, "CODE_LINE=" _sd_STRINGIFY(__LINE__), __func__, format, ap) #define sd_journal_send(...) sd_journal_send_with_location("CODE_FILE=" __FILE__, "CODE_LINE=" _sd_STRINGIFY(__LINE__), __func__, __VA_ARGS__) #define sd_journal_sendv(iovec, n) sd_journal_sendv_with_location("CODE_FILE=" __FILE__, "CODE_LINE=" _sd_STRINGIFY(__LINE__), __func__, iovec, n) +#define sd_journal_perror(message) sd_journal_perror_with_location("CODE_FILE=" __FILE__, "CODE_LINE=" _sd_STRINGIFY(__LINE__), __func__, message) #endif |