journald-stream.c revision 7b77ed8cf36e8eca6017791626044b61ae2d68e7
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen/***
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen This file is part of systemd.
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen Copyright 2011 Lennart Poettering
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen systemd is free software; you can redistribute it and/or modify it
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen under the terms of the GNU Lesser General Public License as published by
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen the Free Software Foundation; either version 2.1 of the License, or
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen (at your option) any later version.
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen systemd is distributed in the hope that it will be useful, but
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen Lesser General Public License for more details.
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen You should have received a copy of the GNU Lesser General Public License
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen***/
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include <fcntl.h>
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include <unistd.h>
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include <stddef.h>
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#ifdef HAVE_SELINUX
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include <selinux/selinux.h>
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#endif
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "sd-event.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "socket-util.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "selinux-util.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "journald-server.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "journald-stream.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "journald-syslog.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "journald-kmsg.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#include "journald-console.h"
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#define STDOUT_STREAMS_MAX 4096
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersentypedef enum StdoutStreamState {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen STDOUT_STREAM_IDENTIFIER,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen STDOUT_STREAM_UNIT_ID,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen STDOUT_STREAM_PRIORITY,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen STDOUT_STREAM_LEVEL_PREFIX,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen STDOUT_STREAM_FORWARD_TO_SYSLOG,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen STDOUT_STREAM_FORWARD_TO_KMSG,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen STDOUT_STREAM_FORWARD_TO_CONSOLE,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen STDOUT_STREAM_RUNNING
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen} StdoutStreamState;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstruct StdoutStream {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen Server *server;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen StdoutStreamState state;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int fd;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen struct ucred ucred;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#ifdef HAVE_SELINUX
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen security_context_t security_context;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#endif
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char *identifier;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char *unit_id;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int priority;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bool level_prefix:1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bool forward_to_syslog:1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bool forward_to_kmsg:1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen bool forward_to_console:1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char buffer[LINE_MAX+1];
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen size_t length;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sd_event_source *event_source;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen LIST_FIELDS(StdoutStream, stdout_stream);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen};
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int stdout_stream_log(StdoutStream *s, const char *p) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen struct iovec iovec[N_IOVEC_META_FIELDS + 5];
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int priority;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char syslog_priority[] = "PRIORITY=\0";
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char syslog_facility[sizeof("SYSLOG_FACILITY=") + DECIMAL_STR_MAX(priority)];
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen _cleanup_free_ char *message = NULL, *syslog_identifier = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen unsigned n = 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char *label = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen size_t label_len = 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(s);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(p);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (isempty(p))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen priority = s->priority;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (s->level_prefix)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen syslog_parse_priority(&p, &priority, false);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (s->forward_to_syslog || s->server->forward_to_syslog)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen server_forward_syslog(s->server, syslog_fixup_facility(priority), s->identifier, p, &s->ucred, NULL);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (s->forward_to_kmsg || s->server->forward_to_kmsg)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen server_forward_kmsg(s->server, priority, s->identifier, p, &s->ucred);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (s->forward_to_console || s->server->forward_to_console)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen server_forward_console(s->server, priority, s->identifier, p, &s->ucred);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=stdout");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen syslog_priority[strlen("PRIORITY=")] = '0' + LOG_PRI(priority);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen IOVEC_SET_STRING(iovec[n++], syslog_priority);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (priority & LOG_FACMASK) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen snprintf(syslog_facility, sizeof(syslog_facility), "SYSLOG_FACILITY=%i", LOG_FAC(priority));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen IOVEC_SET_STRING(iovec[n++], syslog_facility);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (s->identifier) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen syslog_identifier = strappend("SYSLOG_IDENTIFIER=", s->identifier);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (syslog_identifier)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen IOVEC_SET_STRING(iovec[n++], syslog_identifier);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen message = strappend("MESSAGE=", p);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (message)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen IOVEC_SET_STRING(iovec[n++], message);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#ifdef HAVE_SELINUX
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (s->security_context) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen label = (char*) s->security_context;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen label_len = strlen((char*) s->security_context);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#endif
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen server_dispatch_message(s->server, iovec, n, ELEMENTSOF(iovec), &s->ucred, NULL, label, label_len, s->unit_id, priority, 0);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int stdout_stream_line(StdoutStream *s, char *p) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(s);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(p);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen p = strstrip(p);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen switch (s->state) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case STDOUT_STREAM_IDENTIFIER:
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (isempty(p))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->identifier = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->identifier = strdup(p);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!s->identifier)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return log_oom();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->state = STDOUT_STREAM_UNIT_ID;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen case STDOUT_STREAM_UNIT_ID:
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen if (s->ucred.uid == 0) {
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen if (isempty(p))
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->unit_id = NULL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->unit_id = strdup(p);
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen if (!s->unit_id)
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen return log_oom();
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen }
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->state = STDOUT_STREAM_PRIORITY;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case STDOUT_STREAM_PRIORITY:
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = safe_atoi(p, &s->priority);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0 || s->priority < 0 || s->priority > 999) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("Failed to parse log priority line.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -EINVAL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->state = STDOUT_STREAM_LEVEL_PREFIX;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case STDOUT_STREAM_LEVEL_PREFIX:
52d629010db73a9466c359201916494bd55186d1Tom Gundersen r = parse_boolean(p);
52d629010db73a9466c359201916494bd55186d1Tom Gundersen if (r < 0) {
52d629010db73a9466c359201916494bd55186d1Tom Gundersen log_warning("Failed to parse level prefix line.");
52d629010db73a9466c359201916494bd55186d1Tom Gundersen return -EINVAL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->level_prefix = !!r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->state = STDOUT_STREAM_FORWARD_TO_SYSLOG;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
52d629010db73a9466c359201916494bd55186d1Tom Gundersen
52d629010db73a9466c359201916494bd55186d1Tom Gundersen case STDOUT_STREAM_FORWARD_TO_SYSLOG:
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = parse_boolean(p);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("Failed to parse forward to syslog line.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -EINVAL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->forward_to_syslog = !!r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->state = STDOUT_STREAM_FORWARD_TO_KMSG;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case STDOUT_STREAM_FORWARD_TO_KMSG:
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = parse_boolean(p);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("Failed to parse copy to kmsg line.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -EINVAL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->forward_to_kmsg = !!r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->state = STDOUT_STREAM_FORWARD_TO_CONSOLE;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case STDOUT_STREAM_FORWARD_TO_CONSOLE:
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = parse_boolean(p);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("Failed to parse copy to console line.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -EINVAL;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->forward_to_console = !!r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->state = STDOUT_STREAM_RUNNING;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen case STDOUT_STREAM_RUNNING:
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return stdout_stream_log(s, p);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert_not_reached("Unknown stream state");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int stdout_stream_scan(StdoutStream *s, bool force_flush) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char *p;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen size_t remaining;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(s);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen p = s->buffer;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen remaining = s->length;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen for (;;) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen char *end;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen size_t skip;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen end = memchr(p, '\n', remaining);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (end)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen skip = end - p + 1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen else if (remaining >= sizeof(s->buffer) - 1) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen end = p + sizeof(s->buffer) - 1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen skip = remaining;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen break;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen *end = 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = stdout_stream_line(s, p);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen remaining -= skip;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen p += skip;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (force_flush && remaining > 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen p[remaining] = 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = stdout_stream_line(s, p);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen p += remaining;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen remaining = 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (p > s->buffer) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen memmove(s->buffer, p, remaining);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->length = remaining;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen StdoutStream *s = userdata;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen ssize_t l;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(s);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if ((revents|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Got invalid event from epoll for stdout stream: %"PRIx32, revents);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto terminate;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen l = read(s->fd, s->buffer+s->length, sizeof(s->buffer)-1-s->length);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (l < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (errno == EAGAIN)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("Failed to read from stream: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto terminate;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (l == 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen stdout_stream_scan(s, true);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto terminate;
08232a020bd2571088d3ee06dda07732c5e963d1Tom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->length += l;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = stdout_stream_scan(s, false);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto terminate;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 1;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenterminate:
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen stdout_stream_free(s);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenvoid stdout_stream_free(StdoutStream *s) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(s);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (s->server) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(s->server->n_stdout_streams > 0);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->server->n_stdout_streams --;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen LIST_REMOVE(stdout_stream, s->server->stdout_streams, s);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (s->event_source) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen sd_event_source_set_enabled(s->event_source, SD_EVENT_OFF);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->event_source = sd_event_source_unref(s->event_source);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (s->fd >= 0)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen close_nointr_nofail(s->fd);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#ifdef HAVE_SELINUX
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (s->security_context)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen freecon(s->security_context);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#endif
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen free(s->identifier);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen free(s->unit_id);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen free(s);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenstatic int stdout_stream_new(sd_event_source *es, int listen_fd, uint32_t revents, void *userdata) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen Server *s = userdata;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen StdoutStream *stream;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int fd, r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen socklen_t len;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(s);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (revents != EPOLLIN) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Got invalid event from epoll for stdout server fd: %"PRIx32, revents);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -EIO;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen fd = accept4(s->stdout_fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (fd < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (errno == EAGAIN)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to accept stdout connection: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -errno;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (s->n_stdout_streams >= STDOUT_STREAMS_MAX) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_warning("Too many stdout streams, refusing connection.");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen close_nointr_nofail(fd);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen stream = new0(StdoutStream, 1);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (!stream) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen close_nointr_nofail(fd);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return log_oom();
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen stream->fd = fd;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen len = sizeof(stream->ucred);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &stream->ucred, &len) < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to determine peer credentials: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto fail;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#ifdef HAVE_SELINUX
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (use_selinux()) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (getpeercon(fd, &stream->security_context) < 0 && errno != ENOPROTOOPT)
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to determine peer security context: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen#endif
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (shutdown(fd, SHUT_WR) < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to shutdown writing side of socket: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto fail;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_event_add_io(s->event, fd, EPOLLIN, stdout_stream_process, stream, &stream->event_source);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to add stream to event loop: %s", strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto fail;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_event_source_set_priority(stream->event_source, SD_EVENT_PRIORITY_NORMAL+5);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to adjust stdout event source priority: %s", strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen goto fail;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen stream->server = s;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen LIST_PREPEND(stdout_stream, s->stdout_streams, stream);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->n_stdout_streams ++;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenfail:
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen stdout_stream_free(stream);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersenint server_open_stdout_socket(Server *s) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen int r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen assert(s);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (s->stdout_fd < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen union sockaddr_union sa = {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen .un.sun_family = AF_UNIX,
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen .un.sun_path = "/run/systemd/journal/stdout",
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen };
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen s->stdout_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (s->stdout_fd < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("socket() failed: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -errno;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen unlink(sa.un.sun_path);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = bind(s->stdout_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("bind() failed: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -errno;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen chmod(sa.un.sun_path, 0666);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (listen(s->stdout_fd, SOMAXCONN) < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("listen() failed: %m");
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return -errno;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen } else
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen fd_nonblock(s->stdout_fd, 1);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_event_add_io(s->event, s->stdout_fd, EPOLLIN, stdout_stream_new, s, &s->stdout_event_source);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to add stdout server fd to event source: %s", strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen r = sd_event_source_set_priority(s->stdout_event_source, SD_EVENT_PRIORITY_NORMAL+10);
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen if (r < 0) {
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen log_error("Failed to adjust priority of stdout server event source: %s", strerror(-r));
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return r;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen }
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen return 0;
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen}
57fa1d094cd2c5ac68970526ad0a0754c548e75dTom Gundersen