summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2012-07-31 16:09:01 +0200
committerLennart Poettering <lennart@poettering.net>2012-08-01 19:53:23 +0200
commit18c7ed186be28800a2eeb37ad31c9c44480d3d9c (patch)
tree71d39423e738bcd866aff16269ea925c3c7eab17
parent4d9909c93e9c58789c71b34555a1908307c6849e (diff)
downloadsystemd-18c7ed186be28800a2eeb37ad31c9c44480d3d9c.tar.gz
journal: add sd_journal_perror() to API
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac1
-rw-r--r--man/sd_journal_print.xml29
-rw-r--r--man/systemd.journal-fields.xml13
-rw-r--r--src/journal/journal-send.c91
-rw-r--r--src/journal/libsystemd-journal.sym2
-rw-r--r--src/journal/test-journal-send.c5
-rw-r--r--src/systemd/sd-journal.h3
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