summaryrefslogtreecommitdiff
path: root/src
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 /src
parent4d9909c93e9c58789c71b34555a1908307c6849e (diff)
journal: add sd_journal_perror() to API
Diffstat (limited to 'src')
-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
4 files changed, 98 insertions, 3 deletions
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