journald-stream.c revision e3bfb7be07d9b1f4ebb12eb22c4c8bcd2a988d51
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering This file is part of systemd.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Copyright 2011 Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering under the terms of the GNU Lesser General Public License as published by
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (at your option) any later version.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is distributed in the hope that it will be useful, but
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Lesser General Public License for more details.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering You should have received a copy of the GNU Lesser General Public License
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering LIST_FIELDS(StdoutStream, stdout_stream);
d3e84ddb885e9d5f0ae9930eb905910e3a81f157Lennart Poetteringstatic int stdout_stream_log(StdoutStream *s, const char *p) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering struct iovec iovec[N_IOVEC_META_FIELDS + 5];
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering char syslog_facility[sizeof("SYSLOG_FACILITY=") + DECIMAL_STR_MAX(priority)];
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering _cleanup_free_ char *message = NULL, *syslog_identifier = NULL;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering unsigned n = 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering syslog_parse_priority(&p, &priority, false);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (s->forward_to_syslog || s->server->forward_to_syslog)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering server_forward_syslog(s->server, syslog_fixup_facility(priority), s->identifier, p, &s->ucred, NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (s->forward_to_kmsg || s->server->forward_to_kmsg)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering server_forward_kmsg(s->server, priority, s->identifier, p, &s->ucred);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (s->forward_to_console || s->server->forward_to_console)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering server_forward_console(s->server, priority, s->identifier, p, &s->ucred);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=stdout");
b87633c4b20e3221748d6c98336cf6c85123cd66Lennart Poettering syslog_priority[strlen("PRIORITY=")] = '0' + LOG_PRI(priority);
b87633c4b20e3221748d6c98336cf6c85123cd66Lennart Poettering IOVEC_SET_STRING(iovec[n++], syslog_priority);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering snprintf(syslog_facility, sizeof(syslog_facility), "SYSLOG_FACILITY=%i", LOG_FAC(priority));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering IOVEC_SET_STRING(iovec[n++], syslog_facility);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering syslog_identifier = strappend("SYSLOG_IDENTIFIER=", s->identifier);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering IOVEC_SET_STRING(iovec[n++], syslog_identifier);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering label_len = strlen((char*) s->security_context);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering server_dispatch_message(s->server, iovec, n, ELEMENTSOF(iovec), &s->ucred, NULL, label, label_len, s->unit_id, priority, 0);
76b543756ef69ce69784d571aefe8de65eaeb331Lennart Poetteringstatic int stdout_stream_line(StdoutStream *s, char *p) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering if (r < 0 || s->priority < 0 || s->priority > 999) {
19befb2d5fc087f96e40ddc432b2cc9385666209Lennart Poettering log_warning("Failed to parse log priority line.");
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering log_warning("Failed to parse level prefix line.");
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering s->state = STDOUT_STREAM_FORWARD_TO_SYSLOG;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering log_warning("Failed to parse forward to syslog line.");
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering s->state = STDOUT_STREAM_FORWARD_TO_KMSG;
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering log_warning("Failed to parse copy to kmsg line.");
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering s->state = STDOUT_STREAM_FORWARD_TO_CONSOLE;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_warning("Failed to parse copy to console line.");
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering assert_not_reached("Unknown stream state");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int stdout_stream_scan(StdoutStream *s, bool force_flush) {
71fda00f320379f5cbee8e118848de98caaa229dLennart Poettering else if (remaining >= sizeof(s->buffer) - 1) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringint stdout_stream_process(StdoutStream *s) {
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering l = read(s->fd, s->buffer+s->length, sizeof(s->buffer)-1-s->length);
d9e34bfda3d34dcde00a876cb052e7de0655e1cbLennart Poettering log_warning("Failed to read from stream: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringvoid stdout_stream_free(StdoutStream *s) {
c335068380fe8c9d843cdb2cf8a00f822cfabed3Lennart Poettering LIST_REMOVE(stdout_stream, s->server->stdout_streams, s);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (s->fd >= 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering epoll_ctl(s->server->epoll_fd, EPOLL_CTL_DEL, s->fd, NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering fd = accept4(s->stdout_fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to accept stdout connection: %m");
if (!stream) {
return log_oom();
r = -errno;
goto fail;
#ifdef HAVE_SELINUX
if (use_selinux()) {
r = -errno;
goto fail;
r = -errno;
goto fail;
s->n_stdout_streams ++;
fail:
assert(s);
if (s->stdout_fd < 0) {
if (s->stdout_fd < 0) {
return -errno;
r = bind(s->stdout_fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
return -errno;
return -errno;
return -errno;