journald-stream.c revision 2de56f70941eaf91a4520bf33de47a87ebd8b2cb
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering/***
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering This file is part of systemd.
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering Copyright 2011 Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering systemd is free software; you can redistribute it and/or modify it
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering under the terms of the GNU Lesser General Public License as published by
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering (at your option) any later version.
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering systemd is distributed in the hope that it will be useful, but
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering Lesser General Public License for more details.
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering You should have received a copy of the GNU Lesser General Public License
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering***/
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering#include <unistd.h>
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering#include <stddef.h>
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering#ifdef HAVE_SELINUX
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering#include <selinux/selinux.h>
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering#endif
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering#include "sd-event.h"
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering#include "sd-daemon.h"
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering#include "socket-util.h"
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering#include "selinux-util.h"
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering#include "mkdir.h"
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering#include "fileio.h"
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering#include "journald-server.h"
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering#include "journald-stream.h"
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering#include "journald-syslog.h"
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering#include "journald-kmsg.h"
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering#include "journald-console.h"
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering#include "journald-wall.h"
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering#define STDOUT_STREAMS_MAX 4096
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poetteringtypedef enum StdoutStreamState {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering STDOUT_STREAM_IDENTIFIER,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering STDOUT_STREAM_UNIT_ID,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering STDOUT_STREAM_PRIORITY,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering STDOUT_STREAM_LEVEL_PREFIX,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering STDOUT_STREAM_FORWARD_TO_SYSLOG,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering STDOUT_STREAM_FORWARD_TO_KMSG,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering STDOUT_STREAM_FORWARD_TO_CONSOLE,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering STDOUT_STREAM_RUNNING
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering} StdoutStreamState;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poetteringstruct StdoutStream {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering Server *server;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering StdoutStreamState state;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering int fd;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering struct ucred ucred;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering char *label;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering char *identifier;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering char *unit_id;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering int priority;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering bool level_prefix:1;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering bool forward_to_syslog:1;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering bool forward_to_kmsg:1;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering bool forward_to_console:1;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering bool fdstore:1;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering char buffer[LINE_MAX+1];
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering size_t length;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering sd_event_source *event_source;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering char *state_file;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering LIST_FIELDS(StdoutStream, stdout_stream);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering};
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poetteringvoid stdout_stream_free(StdoutStream *s) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (!s)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (s->server) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering assert(s->server->n_stdout_streams > 0);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->server->n_stdout_streams --;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering LIST_REMOVE(stdout_stream, s->server->stdout_streams, s);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (s->event_source) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering sd_event_source_set_enabled(s->event_source, SD_EVENT_OFF);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->event_source = sd_event_source_unref(s->event_source);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering safe_close(s->fd);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering free(s->label);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering free(s->identifier);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering free(s->unit_id);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering free(s->state_file);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering free(s);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering}
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart PoetteringDEFINE_TRIVIAL_CLEANUP_FUNC(StdoutStream*, stdout_stream_free);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poetteringstatic void stdout_stream_destroy(StdoutStream *s) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (!s)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (s->state_file)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering unlink(s->state_file);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering stdout_stream_free(s);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering}
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poetteringstatic int stdout_stream_save(StdoutStream *s) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering _cleanup_free_ char *temp_path = NULL;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering int r;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering assert(s);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (s->state != STDOUT_STREAM_RUNNING)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (!s->state_file) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering struct stat st;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = fstat(s->fd, &st);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (r < 0)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return log_warning_errno(errno, "Failed to stat connected stream: %m");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering /* We use device and inode numbers as identifier for the stream */
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (asprintf(&s->state_file, "/run/systemd/journal/streams/%lu:%lu", (unsigned long) st.st_dev, (unsigned long) st.st_ino) < 0)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return log_oom();
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering mkdir_p("/run/systemd/journal/streams", 0755);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = fopen_temporary(s->state_file, &f, &temp_path);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (r < 0)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering goto finish;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering fprintf(f,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering "# This is private data. Do not parse\n"
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering "PRIORITY=%i\n"
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering "LEVEL_PREFIX=%i\n"
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering "FORWARD_TO_SYSLOG=%i\n"
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering "FORWARD_TO_KMSG=%i\n"
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering "FORWARD_TO_CONSOLE=%i\n",
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->priority,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->level_prefix,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->forward_to_syslog,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->forward_to_kmsg,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->forward_to_console);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (!isempty(s->identifier)) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering _cleanup_free_ char *escaped;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering escaped = cescape(s->identifier);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (!escaped) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = -ENOMEM;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering goto finish;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering fprintf(f, "IDENTIFIER=%s\n", escaped);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (!isempty(s->unit_id)) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering _cleanup_free_ char *escaped;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering escaped = cescape(s->unit_id);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (!escaped) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = -ENOMEM;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering goto finish;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering fprintf(f, "UNIT=%s\n", escaped);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = fflush_and_check(f);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (r < 0)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering goto finish;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (rename(temp_path, s->state_file) < 0) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = -errno;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering goto finish;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering free(temp_path);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering temp_path = NULL;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering /* Store the connection fd in PID 1, so that we get it passed
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering * in again on next start */
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (!s->fdstore) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering sd_pid_notify_with_fds(0, false, "FDSTORE=1", &s->fd, 1);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->fdstore = true;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poetteringfinish:
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (temp_path)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering unlink(temp_path);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (r < 0)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error_errno(r, "Failed to save stream data %s: %m", s->state_file);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return r;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering}
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poetteringstatic int stdout_stream_log(StdoutStream *s, const char *p) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering struct iovec iovec[N_IOVEC_META_FIELDS + 5];
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering int priority;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering char syslog_priority[] = "PRIORITY=\0";
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering char syslog_facility[sizeof("SYSLOG_FACILITY=")-1 + DECIMAL_STR_MAX(int) + 1];
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering _cleanup_free_ char *message = NULL, *syslog_identifier = NULL;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering unsigned n = 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering size_t label_len;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering assert(s);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering assert(p);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (isempty(p))
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering priority = s->priority;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (s->level_prefix)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering syslog_parse_priority(&p, &priority, false);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (s->forward_to_syslog || s->server->forward_to_syslog)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering server_forward_syslog(s->server, syslog_fixup_facility(priority), s->identifier, p, &s->ucred, NULL);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (s->forward_to_kmsg || s->server->forward_to_kmsg)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering server_forward_kmsg(s->server, priority, s->identifier, p, &s->ucred);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (s->forward_to_console || s->server->forward_to_console)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering server_forward_console(s->server, priority, s->identifier, p, &s->ucred);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (s->server->forward_to_wall)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering server_forward_wall(s->server, priority, s->identifier, p, &s->ucred);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=stdout");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering syslog_priority[strlen("PRIORITY=")] = '0' + LOG_PRI(priority);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering IOVEC_SET_STRING(iovec[n++], syslog_priority);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (priority & LOG_FACMASK) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering xsprintf(syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority));
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering IOVEC_SET_STRING(iovec[n++], syslog_facility);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (s->identifier) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering syslog_identifier = strappend("SYSLOG_IDENTIFIER=", s->identifier);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (syslog_identifier)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering IOVEC_SET_STRING(iovec[n++], syslog_identifier);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering message = strappend("MESSAGE=", p);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (message)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering IOVEC_SET_STRING(iovec[n++], message);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering label_len = s->label ? strlen(s->label) : 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering server_dispatch_message(s->server, iovec, n, ELEMENTSOF(iovec), &s->ucred, NULL, s->label, label_len, s->unit_id, priority, 0);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering}
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poetteringstatic int stdout_stream_line(StdoutStream *s, char *p) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering int r;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering assert(s);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering assert(p);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering p = strstrip(p);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering switch (s->state) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering case STDOUT_STREAM_IDENTIFIER:
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (isempty(p))
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->identifier = NULL;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering else {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->identifier = strdup(p);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (!s->identifier)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return log_oom();
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->state = STDOUT_STREAM_UNIT_ID;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering case STDOUT_STREAM_UNIT_ID:
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (s->ucred.uid == 0) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (isempty(p))
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->unit_id = NULL;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering else {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->unit_id = strdup(p);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (!s->unit_id)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return log_oom();
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->state = STDOUT_STREAM_PRIORITY;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering case STDOUT_STREAM_PRIORITY:
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = safe_atoi(p, &s->priority);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (r < 0 || s->priority < 0 || s->priority > 999) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_warning("Failed to parse log priority line.");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return -EINVAL;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->state = STDOUT_STREAM_LEVEL_PREFIX;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering case STDOUT_STREAM_LEVEL_PREFIX:
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = parse_boolean(p);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (r < 0) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_warning("Failed to parse level prefix line.");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return -EINVAL;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->level_prefix = !!r;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->state = STDOUT_STREAM_FORWARD_TO_SYSLOG;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering case STDOUT_STREAM_FORWARD_TO_SYSLOG:
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = parse_boolean(p);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (r < 0) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_warning("Failed to parse forward to syslog line.");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return -EINVAL;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->forward_to_syslog = !!r;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->state = STDOUT_STREAM_FORWARD_TO_KMSG;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering case STDOUT_STREAM_FORWARD_TO_KMSG:
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = parse_boolean(p);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (r < 0) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_warning("Failed to parse copy to kmsg line.");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return -EINVAL;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->forward_to_kmsg = !!r;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->state = STDOUT_STREAM_FORWARD_TO_CONSOLE;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering case STDOUT_STREAM_FORWARD_TO_CONSOLE:
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = parse_boolean(p);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (r < 0) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_warning("Failed to parse copy to console line.");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return -EINVAL;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->forward_to_console = !!r;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->state = STDOUT_STREAM_RUNNING;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering /* Try to save the stream, so that journald can be restarted and we can recover */
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering (void) stdout_stream_save(s);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering case STDOUT_STREAM_RUNNING:
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return stdout_stream_log(s, p);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering assert_not_reached("Unknown stream state");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering}
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poetteringstatic int stdout_stream_scan(StdoutStream *s, bool force_flush) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering char *p;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering size_t remaining;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering int r;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering assert(s);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering p = s->buffer;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering remaining = s->length;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering for (;;) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering char *end;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering size_t skip;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering end = memchr(p, '\n', remaining);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (end)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering skip = end - p + 1;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering else if (remaining >= sizeof(s->buffer) - 1) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering end = p + sizeof(s->buffer) - 1;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering skip = remaining;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering } else
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering break;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering *end = 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = stdout_stream_line(s, p);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (r < 0)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return r;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering remaining -= skip;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering p += skip;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (force_flush && remaining > 0) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering p[remaining] = 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = stdout_stream_line(s, p);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (r < 0)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return r;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering p += remaining;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering remaining = 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (p > s->buffer) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering memmove(s->buffer, p, remaining);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->length = remaining;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering}
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poetteringstatic int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering StdoutStream *s = userdata;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering ssize_t l;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering int r;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering assert(s);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if ((revents|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Got invalid event from epoll for stdout stream: %"PRIx32, revents);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering goto terminate;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering l = read(s->fd, s->buffer+s->length, sizeof(s->buffer)-1-s->length);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (l < 0) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (errno == EAGAIN)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_warning_errno(errno, "Failed to read from stream: %m");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering goto terminate;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (l == 0) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering stdout_stream_scan(s, true);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering goto terminate;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->length += l;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = stdout_stream_scan(s, false);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (r < 0)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering goto terminate;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return 1;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poetteringterminate:
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering stdout_stream_destroy(s);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering}
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poetteringstatic int stdout_stream_install(Server *s, int fd, StdoutStream **ret) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering _cleanup_(stdout_stream_freep) StdoutStream *stream = NULL;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering int r;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering assert(s);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering assert(fd >= 0);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering stream = new0(StdoutStream, 1);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (!stream)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return log_oom();
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering stream->fd = -1;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering stream->priority = LOG_INFO;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = getpeercred(fd, &stream->ucred);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (r < 0)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return log_error_errno(r, "Failed to determine peer credentials: %m");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (mac_selinux_use()) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = getpeersec(fd, &stream->label);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (r < 0 && r != -EOPNOTSUPP)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering (void) log_warning_errno(r, "Failed to determine peer security context: %m");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering (void) shutdown(fd, SHUT_WR);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = sd_event_add_io(s->event, &stream->event_source, fd, EPOLLIN, stdout_stream_process, stream);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (r < 0)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return log_error_errno(r, "Failed to add stream to event loop: %m");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = sd_event_source_set_priority(stream->event_source, SD_EVENT_PRIORITY_NORMAL+5);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (r < 0)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return log_error_errno(r, "Failed to adjust stdout event source priority: %m");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering stream->fd = fd;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering stream->server = s;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering LIST_PREPEND(stdout_stream, s->stdout_streams, stream);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering s->n_stdout_streams ++;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (ret)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering *ret = stream;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering stream = NULL;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering}
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poetteringstatic int stdout_stream_new(sd_event_source *es, int listen_fd, uint32_t revents, void *userdata) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering _cleanup_close_ int fd = -1;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering Server *s = userdata;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering int r;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering assert(s);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (revents != EPOLLIN) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error("Got invalid event from epoll for stdout server fd: %"PRIx32, revents);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return -EIO;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering fd = accept4(s->stdout_fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (fd < 0) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (errno == EAGAIN)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_error_errno(errno, "Failed to accept stdout connection: %m");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return -errno;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (s->n_stdout_streams >= STDOUT_STREAMS_MAX) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_warning("Too many stdout streams, refusing connection.");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = stdout_stream_install(s, fd, NULL);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (r < 0)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return r;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering fd = -1;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering}
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poetteringstatic int stdout_stream_load(StdoutStream *stream, const char *fname) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering _cleanup_free_ char
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering *priority = NULL,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering *level_prefix = NULL,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering *forward_to_syslog = NULL,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering *forward_to_kmsg = NULL,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering *forward_to_console = NULL;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering int r;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering assert(stream);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering assert(fname);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (!stream->state_file) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering stream->state_file = strappend("/run/systemd/journal/streams/", fname);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (!stream->state_file)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return log_oom();
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = parse_env_file(stream->state_file, NEWLINE,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering "PRIORITY", &priority,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering "LEVEL_PREFIX", &level_prefix,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering "FORWARD_TO_SYSLOG", &forward_to_syslog,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering "FORWARD_TO_KMSG", &forward_to_kmsg,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering "FORWARD_TO_CONSOLE", &forward_to_console,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering "IDENTIFIER", &stream->identifier,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering "UNIT", &stream->unit_id,
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering NULL);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (r < 0)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return log_error_errno(r, "Failed to read: %s", stream->state_file);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (priority) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering int p;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering p = log_level_from_string(priority);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (p >= 0)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering stream->priority = p;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (level_prefix) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = parse_boolean(level_prefix);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (r >= 0)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering stream->level_prefix = r;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (forward_to_syslog) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = parse_boolean(forward_to_syslog);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (r >= 0)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering stream->forward_to_syslog = r;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (forward_to_kmsg) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = parse_boolean(forward_to_kmsg);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (r >= 0)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering stream->forward_to_kmsg = r;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (forward_to_console) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = parse_boolean(forward_to_console);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (r >= 0)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering stream->forward_to_console = r;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering}
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poetteringstatic int stdout_stream_restore(Server *s, const char *fname, int fd) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering StdoutStream *stream;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering int r;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering assert(s);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering assert(fname);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering assert(fd >= 0);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (s->n_stdout_streams >= STDOUT_STREAMS_MAX) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering log_warning("Too many stdout streams, refusing restoring of stream.");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return -ENOBUFS;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering r = stdout_stream_install(s, fd, &stream);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (r < 0)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return r;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering stream->state = STDOUT_STREAM_RUNNING;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering stream->fdstore = true;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering /* Ignore all parsing errors */
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering (void) stdout_stream_load(stream, fname);
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering}
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poetteringstatic int server_restore_streams(Server *s, FDSet *fds) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering _cleanup_closedir_ DIR *d = NULL;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering struct dirent *de;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering int r;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering d = opendir("/run/systemd/journal/streams");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (!d) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (errno == ENOENT)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return 0;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering return log_warning_errno(errno, "Failed to enumerate /run/systemd/journal/streams: %m");
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering }
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering FOREACH_DIRENT(de, d, goto fail) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering unsigned long st_dev, st_ino;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering bool found = false;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering Iterator i;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering int fd;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering if (sscanf(de->d_name, "%lu:%lu", &st_dev, &st_ino) != 2)
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering continue;
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering FDSET_FOREACH(fd, fds, i) {
a1ad376761af16da46c9ad90fd8df41c8c5c0976Lennart Poettering struct stat st;
if (fstat(fd, &st) < 0)
return log_error_errno(errno, "Failed to stat %s: %m", de->d_name);
if (S_ISSOCK(st.st_mode) && st.st_dev == st_dev && st.st_ino == st_ino) {
found = true;
break;
}
}
if (!found) {
/* No file descriptor? Then let's delete the state file */
log_debug("Cannot restore stream file %s", de->d_name);
unlinkat(dirfd(d), de->d_name, 0);
continue;
}
fdset_remove(fds, fd);
r = stdout_stream_restore(s, de->d_name, fd);
if (r < 0)
safe_close(fd);
}
return 0;
fail:
return log_error_errno(errno, "Failed to read streams directory: %m");
}
int server_open_stdout_socket(Server *s, FDSet *fds) {
int r;
assert(s);
if (s->stdout_fd < 0) {
union sockaddr_union sa = {
.un.sun_family = AF_UNIX,
.un.sun_path = "/run/systemd/journal/stdout",
};
s->stdout_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
if (s->stdout_fd < 0)
return log_error_errno(errno, "socket() failed: %m");
unlink(sa.un.sun_path);
r = bind(s->stdout_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
if (r < 0)
return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
(void) chmod(sa.un.sun_path, 0666);
if (listen(s->stdout_fd, SOMAXCONN) < 0)
return log_error_errno(errno, "listen(%s) failed: %m", sa.un.sun_path);
} else
fd_nonblock(s->stdout_fd, 1);
r = sd_event_add_io(s->event, &s->stdout_event_source, s->stdout_fd, EPOLLIN, stdout_stream_new, s);
if (r < 0)
return log_error_errno(r, "Failed to add stdout server fd to event source: %m");
r = sd_event_source_set_priority(s->stdout_event_source, SD_EVENT_PRIORITY_NORMAL+10);
if (r < 0)
return log_error_errno(r, "Failed to adjust priority of stdout server event source: %m");
/* Try to restore streams, but don't bother if this fails */
(void) server_restore_streams(s, fds);
return 0;
}