From: Lennart Poettering Date: Tue, 31 Jul 2012 14:09:01 +0000 (+0200) Subject: journal: add sd_journal_perror() to API X-Git-Tag: v188~40 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=18c7ed186be28800a2eeb37ad31c9c44480d3d9c journal: add sd_journal_perror() to API --- diff --git a/Makefile.am b/Makefile.am index cf37ebe62..77aed920a 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 cef2539e2..514529820 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 dfe99192e..7eac6c819 100644 --- a/man/sd_journal_print.xml +++ b/man/sd_journal_print.xml @@ -47,6 +47,7 @@ sd_journal_printv sd_journal_send sd_journal_sendv + sd_journal_perror SD_JOURNAL_SUPPRESS_LOCATION Submit log entries to the journal @@ -81,6 +82,11 @@ int n + + int sd_journal_perror + const char* message + + @@ -150,6 +156,21 @@ particularly useful to submit binary objects to the journal where that is necessary. + sd_journal_perror() is a + similar to + perror3 + 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 + errno3. 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 LOG_ERR (3). + Note that sd_journal_send() is a wrapper around sd_journal_sendv() to make it @@ -191,8 +212,10 @@ sd_journal_send("MESSAGE=Hello World, this is PID %lu!", (unsigned long) getpid( Return Value - The four calls return 0 on success or a - negative errno-style error code. + The four calls return 0 on success or a negative + errno-style error code. The + errno3 + variable itself is not altered. @@ -217,6 +240,8 @@ sd_journal_send("MESSAGE=Hello World, this is PID %lu!", (unsigned long) getpid( sd-journal3, sd_journal_stream_fd3, syslog3, + perror3, + errno3, systemd.journal-fields7 diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml index 6a9fd9d85..59bb8ad70 100644 --- a/man/systemd.journal-fields.xml +++ b/man/systemd.journal-fields.xml @@ -132,6 +132,19 @@ + + ERRNO= + + The low-level Unix error + number causing this entry, if + any. Contains the numeric + value of + errno3 + formatted as decimal + string. + + + SYSLOG_FACILITY= SYSLOG_IDENTIFIER= diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c index bc44828e1..d0f3b725f 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 c33474aea..770f89933 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 9d376d1e5..e708fa440 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 e70f575ce..de1c8f38f 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