diff options
Diffstat (limited to 'src/journal/journal-send.c')
-rw-r--r-- | src/journal/journal-send.c | 90 |
1 files changed, 46 insertions, 44 deletions
diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c index 1e3a463504..440fba67ca 100644 --- a/src/journal/journal-send.c +++ b/src/journal/journal-send.c @@ -1,5 +1,3 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - /*** This file is part of systemd. @@ -19,20 +17,27 @@ along with systemd; If not, see <http://www.gnu.org/licenses/>. ***/ -#include <sys/socket.h> -#include <sys/un.h> #include <errno.h> -#include <stddef.h> -#include <unistd.h> #include <fcntl.h> #include <printf.h> +#include <stddef.h> +#include <sys/socket.h> +#include <sys/un.h> +#include <unistd.h> #define SD_JOURNAL_SUPPRESS_LOCATION #include "sd-journal.h" -#include "util.h" -#include "socket-util.h" + +#include "alloc-util.h" +#include "fd-util.h" +#include "fileio.h" +#include "io-util.h" #include "memfd-util.h" +#include "socket-util.h" +#include "stdio-util.h" +#include "string-util.h" +#include "util.h" #define SNDBUF_SIZE (8*1024*1024) @@ -45,7 +50,7 @@ *_f = alloca(_fl + 10); \ memcpy(*_f, "CODE_FUNC=", 10); \ memcpy(*_f + 10, _func, _fl); \ - } while(false) + } while (false) /* We open a single fd, and we'll share it with the current process, * all its threads, and all its subprocesses. This means we need to @@ -102,6 +107,13 @@ _public_ int sd_journal_printv(int priority, const char *format, va_list ap) { memcpy(buffer, "MESSAGE=", 8); vsnprintf(buffer+8, sizeof(buffer) - 8, format, ap); + /* Strip trailing whitespace, keep prefix whitespace. */ + (void) strstrip(buffer); + + /* Suppress empty lines */ + if (isempty(buffer+8)) + return 0; + zero(iov); IOVEC_SET_STRING(iov[0], buffer); IOVEC_SET_STRING(iov[1], p); @@ -153,6 +165,8 @@ _printf_(1, 0) static int fill_iovec_sprintf(const char *format, va_list ap, int VA_FORMAT_ADVANCE(format, ap); + (void) strstrip(buffer); /* strip trailing whitespace, keep prefixing whitespace */ + IOVEC_SET_STRING(iov[i++], buffer); format = va_arg(ap, char *); @@ -203,28 +217,23 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) { struct iovec *w; uint64_t *l; int i, j = 0; - struct sockaddr_un sa = { - .sun_family = AF_UNIX, - .sun_path = "/run/systemd/journal/socket", + static const union sockaddr_union sa = { + .un.sun_family = AF_UNIX, + .un.sun_path = "/run/systemd/journal/socket", }; struct msghdr mh = { - .msg_name = &sa, - .msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(sa.sun_path), + .msg_name = (struct sockaddr*) &sa.sa, + .msg_namelen = SOCKADDR_UN_LEN(sa.un), }; ssize_t k; - union { - struct cmsghdr cmsghdr; - uint8_t buf[CMSG_SPACE(sizeof(int))]; - } control; - struct cmsghdr *cmsg; bool have_syslog_identifier = false; bool seal = true; assert_return(iov, -EINVAL); assert_return(n > 0, -EINVAL); - w = alloca(sizeof(struct iovec) * n * 5 + 3); - l = alloca(sizeof(uint64_t) * n); + w = newa(struct iovec, n * 5 + 3); + l = newa(uint64_t, n); for (i = 0; i < n; i++) { char *c, *nl; @@ -316,7 +325,7 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) { buffer_fd = memfd_new(NULL); if (buffer_fd < 0) { if (buffer_fd == -ENOSYS) { - buffer_fd = open_tmpfile("/dev/shm", O_RDWR | O_CLOEXEC); + buffer_fd = open_tmpfile_unlinkable("/dev/shm", O_RDWR | O_CLOEXEC); if (buffer_fd < 0) return buffer_fd; @@ -335,26 +344,11 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) { return r; } - mh.msg_iov = NULL; - mh.msg_iovlen = 0; - - zero(control); - mh.msg_control = &control; - mh.msg_controllen = sizeof(control); - - cmsg = CMSG_FIRSTHDR(&mh); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - cmsg->cmsg_len = CMSG_LEN(sizeof(int)); - memcpy(CMSG_DATA(cmsg), &buffer_fd, sizeof(int)); - - mh.msg_controllen = cmsg->cmsg_len; - - k = sendmsg(fd, &mh, MSG_NOSIGNAL); - if (k < 0) - return -errno; - - return 0; + r = send_one_fd_sa(fd, buffer_fd, mh.msg_name, mh.msg_namelen, 0); + if (r == -ENOENT) + /* Fail silently if the journal is not available */ + return 0; + return r; } static int fill_iovec_perror_and_send(const char *message, int skip, struct iovec iov[]) { @@ -385,6 +379,7 @@ static int fill_iovec_perror_and_send(const char *message, int skip, struct iove xsprintf(error, "ERRNO=%i", _saved_errno_); + assert_cc(3 == LOG_ERR); IOVEC_SET_STRING(iov[skip+0], "PRIORITY=3"); IOVEC_SET_STRING(iov[skip+1], buffer); IOVEC_SET_STRING(iov[skip+2], error); @@ -406,7 +401,7 @@ _public_ int sd_journal_perror(const char *message) { } _public_ int sd_journal_stream_fd(const char *identifier, int priority, int level_prefix) { - union sockaddr_union sa = { + static const union sockaddr_union sa = { .un.sun_family = AF_UNIX, .un.sun_path = "/run/systemd/journal/stdout", }; @@ -422,7 +417,7 @@ _public_ int sd_journal_stream_fd(const char *identifier, int priority, int leve if (fd < 0) return -errno; - r = connect(fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)); + r = connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)); if (r < 0) return -errno; @@ -485,6 +480,13 @@ _public_ int sd_journal_printv_with_location(int priority, const char *file, con memcpy(buffer, "MESSAGE=", 8); vsnprintf(buffer+8, sizeof(buffer) - 8, format, ap); + /* Strip trailing whitespace, keep prefixing whitespace */ + (void) strstrip(buffer); + + /* Suppress empty lines */ + if (isempty(buffer+8)) + return 0; + /* func is initialized from __func__ which is not a macro, but * a static const char[], hence cannot easily be prefixed with * CODE_FUNC=, hence let's do it manually here. */ |