a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering/***
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering This file is part of systemd.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Copyright 2011 Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering systemd is free software; you can redistribute it and/or modify it
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering under the terms of the GNU Lesser General Public License as published by
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering (at your option) any later version.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering systemd is distributed in the hope that it will be useful, but
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Lesser General Public License for more details.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering You should have received a copy of the GNU Lesser General Public License
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering***/
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
4871690d9e32608bbd9b18505b5326c2079c9690Allin Cottrell#include <stddef.h>
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include <unistd.h>
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#ifdef HAVE_SELINUX
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#include <selinux/selinux.h>
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#endif
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering#include "sd-daemon.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "sd-event.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "alloc-util.h"
a09561746f15b84da9471b5c4be74e53d19e4f3fLennart Poettering#include "dirent-util.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "escape.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "fd-util.h"
13790add4bf648fed816361794d8277a75253410Lennart Poettering#include "fileio.h"
afc5dbf37fd2399d37976388d9dd9ab470ecf446Lennart Poettering#include "io-util.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "journald-console.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "journald-kmsg.h"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek#include "journald-server.h"
3ffd4af22052963e7a29431721ee204e634bea75Lennart Poettering#include "journald-stream.h"
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#include "journald-syslog.h"
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen#include "journald-wall.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "mkdir.h"
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering#include "parse-util.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "selinux-util.h"
4f5dd3943bef8a04be7e3b838b822bb9a7ad6cb3Lennart Poettering#include "socket-util.h"
15a5e95075a7f6007dd97b2a165c8ed16fe683dfLennart Poettering#include "stdio-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "string-util.h"
7ccbd1ae843d77275f2c542582a9a80e5e058a70Lennart Poettering#include "syslog-util.h"
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering#define STDOUT_STREAMS_MAX 4096
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringtypedef enum StdoutStreamState {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering STDOUT_STREAM_IDENTIFIER,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering STDOUT_STREAM_UNIT_ID,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering STDOUT_STREAM_PRIORITY,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering STDOUT_STREAM_LEVEL_PREFIX,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering STDOUT_STREAM_FORWARD_TO_SYSLOG,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering STDOUT_STREAM_FORWARD_TO_KMSG,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering STDOUT_STREAM_FORWARD_TO_CONSOLE,
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering STDOUT_STREAM_RUNNING
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering} StdoutStreamState;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstruct StdoutStream {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering Server *server;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering StdoutStreamState state;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering int fd;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering struct ucred ucred;
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek char *label;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering char *identifier;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering char *unit_id;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering int priority;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering bool level_prefix:1;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering bool forward_to_syslog:1;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering bool forward_to_kmsg:1;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering bool forward_to_console:1;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering bool fdstore:1;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering bool in_notify_queue:1;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering char buffer[LINE_MAX+1];
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering size_t length;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering sd_event_source *event_source;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering char *state_file;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering LIST_FIELDS(StdoutStream, stdout_stream);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering LIST_FIELDS(StdoutStream, stdout_stream_notify_queue);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering};
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringvoid stdout_stream_free(StdoutStream *s) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!s)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (s->server) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(s->server->n_stdout_streams > 0);
13790add4bf648fed816361794d8277a75253410Lennart Poettering s->server->n_stdout_streams --;
13790add4bf648fed816361794d8277a75253410Lennart Poettering LIST_REMOVE(stdout_stream, s->server->stdout_streams, s);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (s->in_notify_queue)
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering LIST_REMOVE(stdout_stream_notify_queue, s->server->stdout_streams_notify_queue, s);
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (s->event_source) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering sd_event_source_set_enabled(s->event_source, SD_EVENT_OFF);
13790add4bf648fed816361794d8277a75253410Lennart Poettering s->event_source = sd_event_source_unref(s->event_source);
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering safe_close(s->fd);
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek free(s->label);
13790add4bf648fed816361794d8277a75253410Lennart Poettering free(s->identifier);
13790add4bf648fed816361794d8277a75253410Lennart Poettering free(s->unit_id);
13790add4bf648fed816361794d8277a75253410Lennart Poettering free(s->state_file);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering free(s);
13790add4bf648fed816361794d8277a75253410Lennart Poettering}
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart PoetteringDEFINE_TRIVIAL_CLEANUP_FUNC(StdoutStream*, stdout_stream_free);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringstatic void stdout_stream_destroy(StdoutStream *s) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!s)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (s->state_file)
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering (void) unlink(s->state_file);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering stdout_stream_free(s);
13790add4bf648fed816361794d8277a75253410Lennart Poettering}
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringstatic int stdout_stream_save(StdoutStream *s) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering _cleanup_free_ char *temp_path = NULL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering _cleanup_fclose_ FILE *f = NULL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering int r;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(s);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (s->state != STDOUT_STREAM_RUNNING)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return 0;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!s->state_file) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering struct stat st;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = fstat(s->fd, &st);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return log_warning_errno(errno, "Failed to stat connected stream: %m");
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* We use device and inode numbers as identifier for the stream */
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (asprintf(&s->state_file, "/run/systemd/journal/streams/%lu:%lu", (unsigned long) st.st_dev, (unsigned long) st.st_ino) < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return log_oom();
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering mkdir_p("/run/systemd/journal/streams", 0755);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = fopen_temporary(s->state_file, &f, &temp_path);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r < 0)
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering goto fail;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering fprintf(f,
13790add4bf648fed816361794d8277a75253410Lennart Poettering "# This is private data. Do not parse\n"
13790add4bf648fed816361794d8277a75253410Lennart Poettering "PRIORITY=%i\n"
13790add4bf648fed816361794d8277a75253410Lennart Poettering "LEVEL_PREFIX=%i\n"
13790add4bf648fed816361794d8277a75253410Lennart Poettering "FORWARD_TO_SYSLOG=%i\n"
13790add4bf648fed816361794d8277a75253410Lennart Poettering "FORWARD_TO_KMSG=%i\n"
13790add4bf648fed816361794d8277a75253410Lennart Poettering "FORWARD_TO_CONSOLE=%i\n",
13790add4bf648fed816361794d8277a75253410Lennart Poettering s->priority,
13790add4bf648fed816361794d8277a75253410Lennart Poettering s->level_prefix,
13790add4bf648fed816361794d8277a75253410Lennart Poettering s->forward_to_syslog,
13790add4bf648fed816361794d8277a75253410Lennart Poettering s->forward_to_kmsg,
13790add4bf648fed816361794d8277a75253410Lennart Poettering s->forward_to_console);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!isempty(s->identifier)) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering _cleanup_free_ char *escaped;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering escaped = cescape(s->identifier);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!escaped) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = -ENOMEM;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering goto fail;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering fprintf(f, "IDENTIFIER=%s\n", escaped);
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!isempty(s->unit_id)) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering _cleanup_free_ char *escaped;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering escaped = cescape(s->unit_id);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!escaped) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = -ENOMEM;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering goto fail;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering fprintf(f, "UNIT=%s\n", escaped);
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = fflush_and_check(f);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r < 0)
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering goto fail;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (rename(temp_path, s->state_file) < 0) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = -errno;
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering goto fail;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (!s->fdstore && !s->in_notify_queue) {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering LIST_PREPEND(stdout_stream_notify_queue, s->server->stdout_streams_notify_queue, s);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering s->in_notify_queue = true;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (s->server->notify_event_source) {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering r = sd_event_source_set_enabled(s->server->notify_event_source, SD_EVENT_ON);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (r < 0)
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering log_warning_errno(r, "Failed to enable notify event source: %m");
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering return 0;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poetteringfail:
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering (void) unlink(s->state_file);
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering if (temp_path)
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering (void) unlink(temp_path);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
dacd6cee76a08331b8c8616c5f30f70ee49aa2f9Lennart Poettering return log_error_errno(r, "Failed to save stream data %s: %m", s->state_file);
13790add4bf648fed816361794d8277a75253410Lennart Poettering}
13790add4bf648fed816361794d8277a75253410Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int stdout_stream_log(StdoutStream *s, const char *p) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering struct iovec iovec[N_IOVEC_META_FIELDS + 5];
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering int priority;
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek char syslog_priority[] = "PRIORITY=\0";
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek char syslog_facility[sizeof("SYSLOG_FACILITY=")-1 + DECIMAL_STR_MAX(int) + 1];
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek _cleanup_free_ char *message = NULL, *syslog_identifier = NULL;
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek unsigned n = 0;
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek size_t label_len;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(s);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(p);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering priority = s->priority;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (s->level_prefix)
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek syslog_parse_priority(&p, &priority, false);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
6f526243e6a638c2ea7bbdd07b963f57e110d120Evgeny Vereshchagin if (isempty(p))
6f526243e6a638c2ea7bbdd07b963f57e110d120Evgeny Vereshchagin return 0;
6f526243e6a638c2ea7bbdd07b963f57e110d120Evgeny Vereshchagin
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (s->forward_to_syslog || s->server->forward_to_syslog)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering server_forward_syslog(s->server, syslog_fixup_facility(priority), s->identifier, p, &s->ucred, NULL);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (s->forward_to_kmsg || s->server->forward_to_kmsg)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering server_forward_kmsg(s->server, priority, s->identifier, p, &s->ucred);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (s->forward_to_console || s->server->forward_to_console)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering server_forward_console(s->server, priority, s->identifier, p, &s->ucred);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen if (s->server->forward_to_wall)
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen server_forward_wall(s->server, priority, s->identifier, p, &s->ucred);
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=stdout");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek syslog_priority[strlen("PRIORITY=")] = '0' + LOG_PRI(priority);
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], syslog_priority);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek if (priority & LOG_FACMASK) {
5ffa8c818120e35c89becd938d160235c069dd12Zbigniew Jędrzejewski-Szmek xsprintf(syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority));
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek IOVEC_SET_STRING(iovec[n++], syslog_facility);
e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51Zbigniew Jędrzejewski-Szmek }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (s->identifier) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering syslog_identifier = strappend("SYSLOG_IDENTIFIER=", s->identifier);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (syslog_identifier)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering IOVEC_SET_STRING(iovec[n++], syslog_identifier);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering message = strappend("MESSAGE=", p);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (message)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering IOVEC_SET_STRING(iovec[n++], message);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek label_len = s->label ? strlen(s->label) : 0;
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek server_dispatch_message(s->server, iovec, n, ELEMENTSOF(iovec), &s->ucred, NULL, s->label, label_len, s->unit_id, priority, 0);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int stdout_stream_line(StdoutStream *s, char *p) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering int r;
cfa1b98e832026b0fa5f1ca2f8f5f65bddf12a31Evgeny Vereshchagin char *orig;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(s);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(p);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
cfa1b98e832026b0fa5f1ca2f8f5f65bddf12a31Evgeny Vereshchagin orig = p;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering p = strstrip(p);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering switch (s->state) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering case STDOUT_STREAM_IDENTIFIER:
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (isempty(p))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering s->identifier = NULL;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering else {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering s->identifier = strdup(p);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!s->identifier)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return log_oom();
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering s->state = STDOUT_STREAM_UNIT_ID;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering case STDOUT_STREAM_UNIT_ID:
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (s->ucred.uid == 0) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (isempty(p))
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering s->unit_id = NULL;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering else {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering s->unit_id = strdup(p);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (!s->unit_id)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return log_oom();
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering s->state = STDOUT_STREAM_PRIORITY;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering case STDOUT_STREAM_PRIORITY:
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = safe_atoi(p, &s->priority);
41891700e02daf0cab9e86908c76ac6f411bbd57Lennart Poettering if (r < 0 || s->priority < 0 || s->priority > 999) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_warning("Failed to parse log priority line.");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -EINVAL;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering s->state = STDOUT_STREAM_LEVEL_PREFIX;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering case STDOUT_STREAM_LEVEL_PREFIX:
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = parse_boolean(p);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (r < 0) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_warning("Failed to parse level prefix line.");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -EINVAL;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering s->level_prefix = !!r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering s->state = STDOUT_STREAM_FORWARD_TO_SYSLOG;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering case STDOUT_STREAM_FORWARD_TO_SYSLOG:
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = parse_boolean(p);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (r < 0) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_warning("Failed to parse forward to syslog line.");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -EINVAL;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering s->forward_to_syslog = !!r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering s->state = STDOUT_STREAM_FORWARD_TO_KMSG;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering case STDOUT_STREAM_FORWARD_TO_KMSG:
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = parse_boolean(p);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (r < 0) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_warning("Failed to parse copy to kmsg line.");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -EINVAL;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering s->forward_to_kmsg = !!r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering s->state = STDOUT_STREAM_FORWARD_TO_CONSOLE;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering case STDOUT_STREAM_FORWARD_TO_CONSOLE:
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = parse_boolean(p);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (r < 0) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_warning("Failed to parse copy to console line.");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return -EINVAL;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering s->forward_to_console = !!r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering s->state = STDOUT_STREAM_RUNNING;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* Try to save the stream, so that journald can be restarted and we can recover */
13790add4bf648fed816361794d8277a75253410Lennart Poettering (void) stdout_stream_save(s);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering case STDOUT_STREAM_RUNNING:
cfa1b98e832026b0fa5f1ca2f8f5f65bddf12a31Evgeny Vereshchagin return stdout_stream_log(s, orig);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert_not_reached("Unknown stream state");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poetteringstatic int stdout_stream_scan(StdoutStream *s, bool force_flush) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering char *p;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering size_t remaining;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering int r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(s);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering p = s->buffer;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering remaining = s->length;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering for (;;) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering char *end;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering size_t skip;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering end = memchr(p, '\n', remaining);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (end)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering skip = end - p + 1;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering else if (remaining >= sizeof(s->buffer) - 1) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering end = p + sizeof(s->buffer) - 1;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering skip = remaining;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering } else
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering break;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering *end = 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = stdout_stream_line(s, p);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (r < 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering remaining -= skip;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering p += skip;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (force_flush && remaining > 0) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering p[remaining] = 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = stdout_stream_line(s, p);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (r < 0)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering p += remaining;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering remaining = 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (p > s->buffer) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering memmove(s->buffer, p, remaining);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering s->length = remaining;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poetteringstatic int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering StdoutStream *s = userdata;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering ssize_t l;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering int r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(s);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if ((revents|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering log_error("Got invalid event from epoll for stdout stream: %"PRIx32, revents);
91bf3b3e124575f6f647bff29766e9d992f55b32Lennart Poettering goto terminate;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering }
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering l = read(s->fd, s->buffer+s->length, sizeof(s->buffer)-1-s->length);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (l < 0) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (errno == EAGAIN)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidt log_warning_errno(errno, "Failed to read from stream: %m");
91bf3b3e124575f6f647bff29766e9d992f55b32Lennart Poettering goto terminate;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (l == 0) {
7b77ed8cf36e8eca6017791626044b61ae2d68e7Lennart Poettering stdout_stream_scan(s, true);
91bf3b3e124575f6f647bff29766e9d992f55b32Lennart Poettering goto terminate;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering s->length += l;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = stdout_stream_scan(s, false);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (r < 0)
91bf3b3e124575f6f647bff29766e9d992f55b32Lennart Poettering goto terminate;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 1;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
91bf3b3e124575f6f647bff29766e9d992f55b32Lennart Poetteringterminate:
13790add4bf648fed816361794d8277a75253410Lennart Poettering stdout_stream_destroy(s);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringstatic int stdout_stream_install(Server *s, int fd, StdoutStream **ret) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering _cleanup_(stdout_stream_freep) StdoutStream *stream = NULL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering int r;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(s);
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(fd >= 0);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering stream = new0(StdoutStream, 1);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!stream)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return log_oom();
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering stream->fd = -1;
13790add4bf648fed816361794d8277a75253410Lennart Poettering stream->priority = LOG_INFO;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = getpeercred(fd, &stream->ucred);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return log_error_errno(r, "Failed to determine peer credentials: %m");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
6355e75610a8d47fc3ba5ab8bd442172a2cfe574Lennart Poettering if (mac_selinux_have()) {
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek r = getpeersec(fd, &stream->label);
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek if (r < 0 && r != -EOPNOTSUPP)
2de56f70941eaf91a4520bf33de47a87ebd8b2cbZbigniew Jędrzejewski-Szmek (void) log_warning_errno(r, "Failed to determine peer security context: %m");
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering (void) shutdown(fd, SHUT_WR);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = sd_event_add_io(s->event, &stream->event_source, fd, EPOLLIN, stdout_stream_process, stream);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return log_error_errno(r, "Failed to add stream to event loop: %m");
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = sd_event_source_set_priority(stream->event_source, SD_EVENT_PRIORITY_NORMAL+5);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return log_error_errno(r, "Failed to adjust stdout event source priority: %m");
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering stream->fd = fd;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering stream->server = s;
13790add4bf648fed816361794d8277a75253410Lennart Poettering LIST_PREPEND(stdout_stream, s->stdout_streams, stream);
13790add4bf648fed816361794d8277a75253410Lennart Poettering s->n_stdout_streams ++;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (ret)
13790add4bf648fed816361794d8277a75253410Lennart Poettering *ret = stream;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering stream = NULL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poetteringstatic int stdout_stream_new(sd_event_source *es, int listen_fd, uint32_t revents, void *userdata) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering _cleanup_close_ int fd = -1;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering Server *s = userdata;
13790add4bf648fed816361794d8277a75253410Lennart Poettering int r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(s);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (revents != EPOLLIN) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering log_error("Got invalid event from epoll for stdout server fd: %"PRIx32, revents);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering return -EIO;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering }
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering fd = accept4(s->stdout_fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (fd < 0) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (errno == EAGAIN)
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
e1427b138fbf7b7f13bb61187635b882be3ca2b2Michal Schmidt return log_error_errno(errno, "Failed to accept stdout connection: %m");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (s->n_stdout_streams >= STDOUT_STREAMS_MAX) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering log_warning("Too many stdout streams, refusing connection.");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = stdout_stream_install(s, fd, NULL);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return r;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering fd = -1;
13790add4bf648fed816361794d8277a75253410Lennart Poettering return 0;
13790add4bf648fed816361794d8277a75253410Lennart Poettering}
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringstatic int stdout_stream_load(StdoutStream *stream, const char *fname) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering _cleanup_free_ char
13790add4bf648fed816361794d8277a75253410Lennart Poettering *priority = NULL,
13790add4bf648fed816361794d8277a75253410Lennart Poettering *level_prefix = NULL,
13790add4bf648fed816361794d8277a75253410Lennart Poettering *forward_to_syslog = NULL,
13790add4bf648fed816361794d8277a75253410Lennart Poettering *forward_to_kmsg = NULL,
13790add4bf648fed816361794d8277a75253410Lennart Poettering *forward_to_console = NULL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering int r;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(stream);
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(fname);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!stream->state_file) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering stream->state_file = strappend("/run/systemd/journal/streams/", fname);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!stream->state_file)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return log_oom();
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = parse_env_file(stream->state_file, NEWLINE,
13790add4bf648fed816361794d8277a75253410Lennart Poettering "PRIORITY", &priority,
13790add4bf648fed816361794d8277a75253410Lennart Poettering "LEVEL_PREFIX", &level_prefix,
13790add4bf648fed816361794d8277a75253410Lennart Poettering "FORWARD_TO_SYSLOG", &forward_to_syslog,
13790add4bf648fed816361794d8277a75253410Lennart Poettering "FORWARD_TO_KMSG", &forward_to_kmsg,
13790add4bf648fed816361794d8277a75253410Lennart Poettering "FORWARD_TO_CONSOLE", &forward_to_console,
13790add4bf648fed816361794d8277a75253410Lennart Poettering "IDENTIFIER", &stream->identifier,
13790add4bf648fed816361794d8277a75253410Lennart Poettering "UNIT", &stream->unit_id,
13790add4bf648fed816361794d8277a75253410Lennart Poettering NULL);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return log_error_errno(r, "Failed to read: %s", stream->state_file);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (priority) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering int p;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering p = log_level_from_string(priority);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (p >= 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering stream->priority = p;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (level_prefix) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = parse_boolean(level_prefix);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r >= 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering stream->level_prefix = r;
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (forward_to_syslog) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = parse_boolean(forward_to_syslog);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r >= 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering stream->forward_to_syslog = r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (forward_to_kmsg) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = parse_boolean(forward_to_kmsg);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r >= 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering stream->forward_to_kmsg = r;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering }
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (forward_to_console) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = parse_boolean(forward_to_console);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r >= 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering stream->forward_to_console = r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return 0;
13790add4bf648fed816361794d8277a75253410Lennart Poettering}
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringstatic int stdout_stream_restore(Server *s, const char *fname, int fd) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering StdoutStream *stream;
13790add4bf648fed816361794d8277a75253410Lennart Poettering int r;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(s);
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(fname);
13790add4bf648fed816361794d8277a75253410Lennart Poettering assert(fd >= 0);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (s->n_stdout_streams >= STDOUT_STREAMS_MAX) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_warning("Too many stdout streams, refusing restoring of stream.");
13790add4bf648fed816361794d8277a75253410Lennart Poettering return -ENOBUFS;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = stdout_stream_install(s, fd, &stream);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return r;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering stream->state = STDOUT_STREAM_RUNNING;
13790add4bf648fed816361794d8277a75253410Lennart Poettering stream->fdstore = true;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* Ignore all parsing errors */
13790add4bf648fed816361794d8277a75253410Lennart Poettering (void) stdout_stream_load(stream, fname);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
13790add4bf648fed816361794d8277a75253410Lennart Poettering}
13790add4bf648fed816361794d8277a75253410Lennart Poettering
15d91bff36c61d38df8edff258d1702a017a0e66Zbigniew Jędrzejewski-Szmekint server_restore_streams(Server *s, FDSet *fds) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering _cleanup_closedir_ DIR *d = NULL;
13790add4bf648fed816361794d8277a75253410Lennart Poettering struct dirent *de;
13790add4bf648fed816361794d8277a75253410Lennart Poettering int r;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering d = opendir("/run/systemd/journal/streams");
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!d) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (errno == ENOENT)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return 0;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering return log_warning_errno(errno, "Failed to enumerate /run/systemd/journal/streams: %m");
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering FOREACH_DIRENT(de, d, goto fail) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering unsigned long st_dev, st_ino;
13790add4bf648fed816361794d8277a75253410Lennart Poettering bool found = false;
13790add4bf648fed816361794d8277a75253410Lennart Poettering Iterator i;
13790add4bf648fed816361794d8277a75253410Lennart Poettering int fd;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (sscanf(de->d_name, "%lu:%lu", &st_dev, &st_ino) != 2)
13790add4bf648fed816361794d8277a75253410Lennart Poettering continue;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering FDSET_FOREACH(fd, fds, i) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering struct stat st;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (fstat(fd, &st) < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering return log_error_errno(errno, "Failed to stat %s: %m", de->d_name);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (S_ISSOCK(st.st_mode) && st.st_dev == st_dev && st.st_ino == st_ino) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering found = true;
13790add4bf648fed816361794d8277a75253410Lennart Poettering break;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (!found) {
13790add4bf648fed816361794d8277a75253410Lennart Poettering /* No file descriptor? Then let's delete the state file */
13790add4bf648fed816361794d8277a75253410Lennart Poettering log_debug("Cannot restore stream file %s", de->d_name);
13790add4bf648fed816361794d8277a75253410Lennart Poettering unlinkat(dirfd(d), de->d_name, 0);
13790add4bf648fed816361794d8277a75253410Lennart Poettering continue;
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering fdset_remove(fds, fd);
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poettering r = stdout_stream_restore(s, de->d_name, fd);
13790add4bf648fed816361794d8277a75253410Lennart Poettering if (r < 0)
13790add4bf648fed816361794d8277a75253410Lennart Poettering safe_close(fd);
13790add4bf648fed816361794d8277a75253410Lennart Poettering }
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
7b77ed8cf36e8eca6017791626044b61ae2d68e7Lennart Poettering return 0;
13790add4bf648fed816361794d8277a75253410Lennart Poettering
13790add4bf648fed816361794d8277a75253410Lennart Poetteringfail:
13790add4bf648fed816361794d8277a75253410Lennart Poettering return log_error_errno(errno, "Failed to read streams directory: %m");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
15d91bff36c61d38df8edff258d1702a017a0e66Zbigniew Jędrzejewski-Szmekint server_open_stdout_socket(Server *s) {
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering int r;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering assert(s);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering if (s->stdout_fd < 0) {
b92bea5d2a9481de69bb627a7b442a9f58fca43dZbigniew Jędrzejewski-Szmek union sockaddr_union sa = {
b92bea5d2a9481de69bb627a7b442a9f58fca43dZbigniew Jędrzejewski-Szmek .un.sun_family = AF_UNIX,
b92bea5d2a9481de69bb627a7b442a9f58fca43dZbigniew Jędrzejewski-Szmek .un.sun_path = "/run/systemd/journal/stdout",
b92bea5d2a9481de69bb627a7b442a9f58fca43dZbigniew Jędrzejewski-Szmek };
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering s->stdout_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt if (s->stdout_fd < 0)
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return log_error_errno(errno, "socket() failed: %m");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering unlink(sa.un.sun_path);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering r = bind(s->stdout_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt if (r < 0)
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return log_error_errno(errno, "bind(%s) failed: %m", sa.un.sun_path);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
4a61c3e51e96a747c30598d78ee3a24e7c569e9fZbigniew Jędrzejewski-Szmek (void) chmod(sa.un.sun_path, 0666);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt if (listen(s->stdout_fd, SOMAXCONN) < 0)
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return log_error_errno(errno, "listen(%s) failed: %m", sa.un.sun_path);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering } else
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering fd_nonblock(s->stdout_fd, 1);
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering r = sd_event_add_io(s->event, &s->stdout_event_source, s->stdout_fd, EPOLLIN, stdout_stream_new, s);
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt if (r < 0)
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt return log_error_errno(r, "Failed to add stdout server fd to event source: %m");
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering
48cef29504b1ffc0df9929f2d8b2af2ad74d2b4aVito Caputo r = sd_event_source_set_priority(s->stdout_event_source, SD_EVENT_PRIORITY_NORMAL+5);
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt if (r < 0)
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt return log_error_errno(r, "Failed to adjust priority of stdout server event source: %m");
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering return 0;
a45b9fca6b91a767dcd9060cfcb30617dad234c7Lennart Poettering}
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poetteringvoid stdout_stream_send_notify(StdoutStream *s) {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering struct iovec iovec = {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering .iov_base = (char*) "FDSTORE=1",
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering .iov_len = strlen("FDSTORE=1"),
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering };
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering struct msghdr msghdr = {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering .msg_iov = &iovec,
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering .msg_iovlen = 1,
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering };
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering struct cmsghdr *cmsg;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering ssize_t l;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering assert(s);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering assert(!s->fdstore);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering assert(s->in_notify_queue);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering assert(s->server);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering assert(s->server->notify_fd >= 0);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering /* Store the connection fd in PID 1, so that we get it passed
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering * in again on next start */
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering msghdr.msg_controllen = CMSG_SPACE(sizeof(int));
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering msghdr.msg_control = alloca0(msghdr.msg_controllen);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering cmsg = CMSG_FIRSTHDR(&msghdr);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering cmsg->cmsg_level = SOL_SOCKET;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering cmsg->cmsg_type = SCM_RIGHTS;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering cmsg->cmsg_len = CMSG_LEN(sizeof(int));
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering memcpy(CMSG_DATA(cmsg), &s->fd, sizeof(int));
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering l = sendmsg(s->server->notify_fd, &msghdr, MSG_DONTWAIT|MSG_NOSIGNAL);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (l < 0) {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering if (errno == EAGAIN)
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering return;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering log_error_errno(errno, "Failed to send stream file descriptor to service manager: %m");
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering } else {
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering log_debug("Successfully sent stream file descriptor to service manager.");
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering s->fdstore = 1;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering }
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering LIST_REMOVE(stdout_stream_notify_queue, s->server->stdout_streams_notify_queue, s);
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering s->in_notify_queue = false;
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering
e22aa3d3284709234f086ebebc13a905a295b7a7Lennart Poettering}