journal-send.c revision a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0a
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering/***
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering This file is part of systemd.
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering Copyright 2011 Lennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering systemd is free software; you can redistribute it and/or modify it
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering under the terms of the GNU General Public License as published by
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering the Free Software Foundation; either version 2 of the License, or
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering (at your option) any later version.
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering systemd is distributed in the hope that it will be useful, but
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering General Public License for more details.
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering You should have received a copy of the GNU General Public License
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering***/
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering#include <sys/socket.h>
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering#include <sys/un.h>
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering#include <errno.h>
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering#include <stddef.h>
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering#include "sd-journal.h"
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering#include "util.h"
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering#include "socket-util.h"
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering/* We open a single fd, and we'll share it with the current process,
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * all its threads, and all its subprocesses. This means we need to
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * initialize it atomically, and need to operate on it atomically
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * never assuming we are the only user */
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringstatic int journal_fd(void) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering int fd;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering static int fd_plus_one = 0;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringretry:
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (fd_plus_one > 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return fd_plus_one - 1;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (fd < 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return -errno;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (!__sync_bool_compare_and_swap(&fd_plus_one, 0, fd+1)) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering close_nointr_nofail(fd);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering goto retry;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return fd;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering}
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0aLennart Poettering_public_ int sd_journal_print(int priority, const char *format, ...) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering int r;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering va_list ap;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering va_start(ap, format);
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering r = sd_journal_printv(priority, format, ap);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering va_end(ap);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return r;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering}
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0aLennart Poettering_public_ int sd_journal_printv(int priority, const char *format, va_list ap) {
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering char buffer[8 + LINE_MAX], p[11];
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering struct iovec iov[2];
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (priority < 0 || priority > 7)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -EINVAL;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (!format)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -EINVAL;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering snprintf(p, sizeof(p), "PRIORITY=%i", priority & LOG_PRIMASK);
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering char_array_0(p);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering memcpy(buffer, "MESSAGE=", 8);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering vsnprintf(buffer+8, sizeof(buffer) - 8, format, ap);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering char_array_0(buffer);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering zero(iov);
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering IOVEC_SET_STRING(iov[0], buffer);
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering IOVEC_SET_STRING(iov[1], p);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering return sd_journal_sendv(iov, 2);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering}
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0aLennart Poettering_public_ int sd_journal_send(const char *format, ...) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering int r, n = 0, i = 0, j;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering va_list ap;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering struct iovec *iov = NULL;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering va_start(ap, format);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering while (format) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering struct iovec *c;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering char *buffer;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (i >= n) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering n = MAX(i*2, 4);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering c = realloc(iov, n * sizeof(struct iovec));
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (!c) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering r = -ENOMEM;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering goto fail;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering iov = c;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (vasprintf(&buffer, format, ap) < 0) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering r = -ENOMEM;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering goto fail;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering IOVEC_SET_STRING(iov[i++], buffer);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering format = va_arg(ap, char *);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering va_end(ap);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering r = sd_journal_sendv(iov, i);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringfail:
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering for (j = 0; j < i; j++)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering free(iov[j].iov_base);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering free(iov);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return r;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering}
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0aLennart Poettering_public_ int sd_journal_sendv(const struct iovec *iov, int n) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering int fd;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering struct iovec *w;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering uint64_t *l;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering int i, j = 0;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering struct msghdr mh;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering struct sockaddr_un sa;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (!iov || n <= 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return -EINVAL;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering w = alloca(sizeof(struct iovec) * n * 5);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering l = alloca(sizeof(uint64_t) * n);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering for (i = 0; i < n; i++) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering char *c, *nl;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0aLennart Poettering if (!iov[i].iov_base ||
a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0aLennart Poettering iov[i].iov_len <= 1)
a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0aLennart Poettering return -EINVAL;
a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0aLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering c = memchr(iov[i].iov_base, '=', iov[i].iov_len);
a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0aLennart Poettering if (!c || c == iov[i].iov_base)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return -EINVAL;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering nl = memchr(iov[i].iov_base, '\n', iov[i].iov_len);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (nl) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (nl < c)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return -EINVAL;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering /* Already includes a newline? Bummer, then
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * let's write the variable name, then a
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * newline, then the size (64bit LE), followed
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * by the data and a final newline */
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering w[j].iov_base = iov[i].iov_base;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering w[j].iov_len = c - (char*) iov[i].iov_base;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering j++;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering IOVEC_SET_STRING(w[j++], "\n");
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering l[i] = htole64(iov[i].iov_len - (c - (char*) iov[i].iov_base) - 1);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering w[j].iov_base = &l[i];
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering w[j].iov_len = sizeof(uint64_t);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering j++;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering w[j].iov_base = c + 1;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering w[j].iov_len = iov[i].iov_len - (c - (char*) iov[i].iov_base) - 1;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering j++;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering } else
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering /* Nothing special? Then just add the line and
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * append a newline */
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering w[j++] = iov[i];
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering IOVEC_SET_STRING(w[j++], "\n");
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering fd = journal_fd();
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (fd < 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return fd;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering zero(sa);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering sa.sun_family = AF_UNIX;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering strncpy(sa.sun_path,"/run/systemd/journal", sizeof(sa.sun_path));
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering zero(mh);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering mh.msg_name = &sa;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering mh.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(sa.sun_path);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering mh.msg_iov = w;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering mh.msg_iovlen = j;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (sendmsg(fd, &mh, MSG_NOSIGNAL) < 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return -errno;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return 0;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering}
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0aLennart Poettering_public_ int sd_journal_stream_fd(const char *tag, int priority, int priority_prefix) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering union sockaddr_union sa;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering int fd;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering char *header;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering size_t l;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering ssize_t r;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (priority < 0 || priority > 7)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -EINVAL;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (fd < 0)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -errno;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering zero(sa);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering sa.un.sun_family = AF_UNIX;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering strncpy(sa.un.sun_path, "/run/systemd/stdout", sizeof(sa.un.sun_path));
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering r = connect(fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (r < 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering close_nointr_nofail(fd);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -errno;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (!tag)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering tag = "";
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering l = strlen(tag);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering header = alloca(l + 1 + 2 + 2 + 2);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering memcpy(header, tag, l);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering header[l++] = '\n';
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering header[l++] = '0' + priority;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering header[l++] = '\n';
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering header[l++] = '0' + !!priority_prefix;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering header[l++] = '\n';
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering header[l++] = '0';
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering header[l++] = '\n';
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering r = loop_write(fd, header, l, false);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (r < 0) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering close_nointr_nofail(fd);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return (int) r;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if ((size_t) r != l) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering close_nointr_nofail(fd);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -errno;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return fd;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering}