journal-send.c revision b070e7f3c9ed680c821bd89d42506695f2438506
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/***
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering This file is part of systemd.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Copyright 2011 Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering under the terms of the GNU General Public License as published by
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering the Free Software Foundation; either version 2 of the License, or
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (at your option) any later version.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is distributed in the hope that it will be useful, but
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering General Public License for more details.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering You should have received a copy of the GNU General Public License
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering***/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
8bdbb8d9cbe1d35708385573d70984ab4533812dLennart Poettering#include <sys/socket.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <sys/un.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <errno.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <stddef.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <unistd.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <fcntl.h>
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering#define SD_JOURNAL_SUPPRESS_LOCATION
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering#include "sd-journal.h"
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering#include "util.h"
eef46c372f64f40dd75415b2c504c73138719c8dLennart Poettering#include "socket-util.h"
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#define SNDBUF_SIZE (8*1024*1024)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/* We open a single fd, and we'll share it with the current process,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * all its threads, and all its subprocesses. This means we need to
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering * initialize it atomically, and need to operate on it atomically
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen * never assuming we are the only user */
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int journal_fd(void) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int fd;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering static int fd_plus_one = 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poetteringretry:
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering if (fd_plus_one > 0)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return fd_plus_one - 1;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (fd < 0)
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return -errno;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering fd_inc_sndbuf(fd, SNDBUF_SIZE);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!__sync_bool_compare_and_swap(&fd_plus_one, 0, fd+1)) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering close_nointr_nofail(fd);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto retry;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return fd;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering_public_ int sd_journal_print(int priority, const char *format, ...) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering int r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering va_list ap;
d8f52ed25a9edce75fda5251c977b7898e33887eLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering va_start(ap, format);
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering r = sd_journal_printv(priority, format, ap);
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering va_end(ap);
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering
6e18cc9fa078d2a967251017ddb5baefb104b720Lennart Poettering return r;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering}
587fec427c80b6c34dcf1d7570f891fcb652a7c5Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering_public_ int sd_journal_printv(int priority, const char *format, va_list ap) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char buffer[8 + LINE_MAX], p[11];
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering struct iovec iov[2];
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (priority < 0 || priority > 7)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EINVAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!format)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EINVAL;
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering snprintf(p, sizeof(p), "PRIORITY=%i", priority & LOG_PRIMASK);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering char_array_0(p);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering memcpy(buffer, "MESSAGE=", 8);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering vsnprintf(buffer+8, sizeof(buffer) - 8, format, ap);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering char_array_0(buffer);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering zero(iov);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering IOVEC_SET_STRING(iov[0], buffer);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering IOVEC_SET_STRING(iov[1], p);
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering
acf97e213e69a97e63ab8f7fad7ecd53608c757aLennart Poettering return sd_journal_sendv(iov, 2);
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering}
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poetteringstatic int fill_iovec_sprintf(const char *format, va_list ap, int extra, struct iovec **_iov) {
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering int r, n = 0, i, j;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering struct iovec *iov = NULL;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering int saved_errno;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering assert(_iov);
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering saved_errno = errno;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (extra > 0) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering n = MAX(extra * 2, extra + 4);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering iov = malloc0(n * sizeof(struct iovec));
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (!iov) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering r = -ENOMEM;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering goto fail;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering }
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering i = extra;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering } else
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering i = 0;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering while (format) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering struct iovec *c;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen char *buffer;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (i >= n) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen n = MAX(i*2, 4);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering c = realloc(iov, n * sizeof(struct iovec));
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (!c) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = -ENOMEM;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto fail;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering }
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering iov = c;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (vasprintf(&buffer, format, ap) < 0) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = -ENOMEM;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen goto fail;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen IOVEC_SET_STRING(iov[i++], buffer);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering format = va_arg(ap, char *);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering *_iov = iov;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering errno = saved_errno;
3d7415f43f0fe6a821d7bc4a341ba371e8a30ef3Lennart Poettering return i;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poetteringfail:
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering for (j = 0; j < i; j++)
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen free(iov[j].iov_base);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering free(iov);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering errno = saved_errno;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering}
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering_public_ int sd_journal_send(const char *format, ...) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering int r, i, j;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering va_list ap;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering struct iovec *iov = NULL;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering va_start(ap, format);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering i = fill_iovec_sprintf(format, ap, 0, &iov);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering va_end(ap);
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering if (_unlikely_(i < 0)) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering r = i;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering goto finish;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering }
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering r = sd_journal_sendv(iov, i);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenfinish:
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering for (j = 0; j < i; j++)
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen free(iov[j].iov_base);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen free(iov);
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering}
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering_public_ int sd_journal_sendv(const struct iovec *iov, int n) {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering int fd, buffer_fd;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering struct iovec *w;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering uint64_t *l;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering int r, i, j = 0;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering struct msghdr mh;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering struct sockaddr_un sa;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering ssize_t k;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering int saved_errno;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering union {
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering struct cmsghdr cmsghdr;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering uint8_t buf[CMSG_SPACE(sizeof(int))];
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen } control;
0b63e2789f984e84f40bf6e49f5da15c87298cedLennart Poettering struct cmsghdr *cmsg;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* We use /dev/shm instead of /tmp here, since we want this to
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * be a tmpfs, and one that is available from early boot on
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * and where unprivileged users can create files. */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char path[] = "/dev/shm/journal.XXXXXX";
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (_unlikely_(!iov))
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return -EINVAL;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (_unlikely_(n <= 0))
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering return -EINVAL;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering saved_errno = errno;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering w = alloca(sizeof(struct iovec) * n * 5);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering l = alloca(sizeof(uint64_t) * n);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering for (i = 0; i < n; i++) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering char *c, *nl;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (_unlikely_(!iov[i].iov_base || iov[i].iov_len <= 1)) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = -EINVAL;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering goto finish;
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering c = memchr(iov[i].iov_base, '=', iov[i].iov_len);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (_unlikely_(!c || c == iov[i].iov_base)) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = -EINVAL;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering goto finish;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering }
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering nl = memchr(iov[i].iov_base, '\n', iov[i].iov_len);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (nl) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (_unlikely_(nl < c)) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = -EINVAL;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering goto finish;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering /* Already includes a newline? Bummer, then
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering * let's write the variable name, then a
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering * newline, then the size (64bit LE), followed
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering * by the data and a final newline */
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering w[j].iov_base = iov[i].iov_base;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering w[j].iov_len = c - (char*) iov[i].iov_base;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering j++;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering IOVEC_SET_STRING(w[j++], "\n");
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering l[i] = htole64(iov[i].iov_len - (c - (char*) iov[i].iov_base) - 1);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering w[j].iov_base = &l[i];
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering w[j].iov_len = sizeof(uint64_t);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering j++;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering w[j].iov_base = c + 1;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering w[j].iov_len = iov[i].iov_len - (c - (char*) iov[i].iov_base) - 1;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering j++;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering } else
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering /* Nothing special? Then just add the line and
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering * append a newline */
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering w[j++] = iov[i];
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering IOVEC_SET_STRING(w[j++], "\n");
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering fd = journal_fd();
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (_unlikely_(fd < 0)) {
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering r = fd;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering goto finish;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering }
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering zero(sa);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering sa.sun_family = AF_UNIX;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering strncpy(sa.sun_path, "/run/systemd/journal/socket", sizeof(sa.sun_path));
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering zero(mh);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering mh.msg_name = &sa;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering mh.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(sa.sun_path);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering mh.msg_iov = w;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering mh.msg_iovlen = j;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering k = sendmsg(fd, &mh, MSG_NOSIGNAL);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (k >= 0) {
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering r = 0;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering goto finish;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering }
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (errno != EMSGSIZE && errno != ENOBUFS) {
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering r = -errno;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering goto finish;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering }
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering /* Message doesn't fit... Let's dump the data in a temporary
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering * file and just pass a file descriptor of it to the other
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering * side */
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering buffer_fd = mkostemp(path, O_CLOEXEC|O_RDWR);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (buffer_fd < 0) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = -errno;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering goto finish;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (unlink(path) < 0) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering close_nointr_nofail(buffer_fd);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = -errno;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering goto finish;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering n = writev(buffer_fd, w, j);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (n < 0) {
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering close_nointr_nofail(buffer_fd);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering r = -errno;
c19de71113f956809995fc68817e055e9f61f607Lennart Poettering goto finish;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering }
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering mh.msg_iov = NULL;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering mh.msg_iovlen = 0;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering zero(control);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering mh.msg_control = &control;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering mh.msg_controllen = sizeof(control);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
8937e7b68940d0fa0d0aab90eb7425fa7dccebc9Lennart Poettering cmsg = CMSG_FIRSTHDR(&mh);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering cmsg->cmsg_level = SOL_SOCKET;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering cmsg->cmsg_type = SCM_RIGHTS;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering cmsg->cmsg_len = CMSG_LEN(sizeof(int));
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering memcpy(CMSG_DATA(cmsg), &buffer_fd, sizeof(int));
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering mh.msg_controllen = cmsg->cmsg_len;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering k = sendmsg(fd, &mh, MSG_NOSIGNAL);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering close_nointr_nofail(buffer_fd);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (k < 0) {
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering r = -errno;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen goto finish;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering r = 0;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poetteringfinish:
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering errno = saved_errno;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return r;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering}
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering_public_ int sd_journal_stream_fd(const char *identifier, int priority, int level_prefix) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering union sockaddr_union sa;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering int fd;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering char *header;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering size_t l;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering ssize_t r;
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (priority < 0 || priority > 7)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return -EINVAL;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering if (fd < 0)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return -errno;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering zero(sa);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering sa.un.sun_family = AF_UNIX;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen strncpy(sa.un.sun_path, "/run/systemd/journal/stdout", sizeof(sa.un.sun_path));
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering r = connect(fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (r < 0) {
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering close_nointr_nofail(fd);
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering return -errno;
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering }
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering if (shutdown(fd, SHUT_RD) < 0) {
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering close_nointr_nofail(fd);
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering return -errno;
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering }
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering fd_inc_sndbuf(fd, SNDBUF_SIZE);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (!identifier)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering identifier = "";
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering l = strlen(identifier);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering header = alloca(l + 1 + 2 + 2 + 2 + 2 + 2);
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering memcpy(header, identifier, l);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering header[l++] = '\n';
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering header[l++] = '0' + priority;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering header[l++] = '\n';
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering header[l++] = '0' + !!level_prefix;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering header[l++] = '\n';
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering header[l++] = '0';
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering header[l++] = '\n';
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering header[l++] = '0';
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering header[l++] = '\n';
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering header[l++] = '0';
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering header[l++] = '\n';
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = loop_write(fd, header, l, false);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (r < 0) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering close_nointr_nofail(fd);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return (int) r;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if ((size_t) r != l) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering close_nointr_nofail(fd);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return -errno;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return fd;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering}
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering_public_ int sd_journal_print_with_location(int priority, const char *file, const char *line, const char *func, const char *format, ...) {
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering int r;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering va_list ap;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering va_start(ap, format);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = sd_journal_printv_with_location(priority, file, line, func, format, ap);
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering va_end(ap);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return r;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering}
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering_public_ int sd_journal_printv_with_location(int priority, const char *file, const char *line, const char *func, const char *format, va_list ap) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering char buffer[8 + LINE_MAX], p[11];
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering struct iovec iov[5];
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering char *f;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering size_t fl;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (priority < 0 || priority > 7)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return -EINVAL;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (_unlikely_(!format))
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return -EINVAL;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering snprintf(p, sizeof(p), "PRIORITY=%i", priority & LOG_PRIMASK);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering char_array_0(p);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering memcpy(buffer, "MESSAGE=", 8);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering vsnprintf(buffer+8, sizeof(buffer) - 8, format, ap);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering char_array_0(buffer);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering /* func is initialized from __func__ which is not a macro, but
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering * a static const char[], hence cannot easily be prefixed with
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering * CODE_FUNC=, hence let's do it manually here. */
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering fl = strlen(func);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering f = alloca(fl + 10);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering memcpy(f, "CODE_FUNC=", 10);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering memcpy(f + 10, func, fl + 1);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering zero(iov);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering IOVEC_SET_STRING(iov[0], buffer);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering IOVEC_SET_STRING(iov[1], p);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering IOVEC_SET_STRING(iov[2], file);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering IOVEC_SET_STRING(iov[3], line);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering IOVEC_SET_STRING(iov[4], f);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return sd_journal_sendv(iov, ELEMENTSOF(iov));
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering}
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering_public_ int sd_journal_send_with_location(const char *file, const char *line, const char *func, const char *format, ...) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering int r, i, j;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering va_list ap;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering struct iovec *iov = NULL;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering char *f;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering size_t fl;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering va_start(ap, format);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering i = fill_iovec_sprintf(format, ap, 3, &iov);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering va_end(ap);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (_unlikely_(i < 0)) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering r = i;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering goto finish;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering }
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering fl = strlen(func);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering f = alloca(fl + 10);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering memcpy(f, "CODE_FUNC=", 10);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering memcpy(f + 10, func, fl + 1);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering IOVEC_SET_STRING(iov[0], file);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering IOVEC_SET_STRING(iov[1], line);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering IOVEC_SET_STRING(iov[2], f);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering r = sd_journal_sendv(iov, i);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poetteringfinish:
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering for (j = 3; j < i; j++)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering free(iov[j].iov_base);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering free(iov);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers}
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering_public_ int sd_journal_sendv_with_location(const char *file, const char *line, const char *func, const struct iovec *iov, int n) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers struct iovec *niov;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char *f;
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering size_t fl;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (_unlikely_(!iov))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EINVAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (_unlikely_(n <= 0))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EINVAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering niov = alloca(sizeof(struct iovec) * (n + 3));
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering memcpy(niov, iov, sizeof(struct iovec) * n);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering fl = strlen(func);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering f = alloca(fl + 10);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering memcpy(f, "CODE_FUNC=", 10);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering memcpy(f + 10, func, fl + 1);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering IOVEC_SET_STRING(niov[n++], file);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering IOVEC_SET_STRING(niov[n++], line);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering IOVEC_SET_STRING(niov[n++], f);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering return sd_journal_sendv(niov, n);
8b0cc9a36c8f92f010f2e8465942d2cd7c580d78Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering