journald-stream.c revision 14c1025934e709d07948c13ca62b40c35c91d111
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer This file is part of systemd.
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer Copyright 2011 Lennart Poettering
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer systemd is free software; you can redistribute it and/or modify it
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer under the terms of the GNU Lesser General Public License as published by
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer the Free Software Foundation; either version 2.1 of the License, or
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer (at your option) any later version.
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer systemd is distributed in the hope that it will be useful, but
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer WITHOUT ANY WARRANTY; without even the implied warranty of
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer Lesser General Public License for more details.
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer You should have received a copy of the GNU Lesser General Public License
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer along with systemd; If not, see <http://www.gnu.org/licenses/>.
510b857f7d1e7e8d38912890536342dd5dd647ddLennart Poettering LIST_FIELDS(StdoutStream, stdout_stream);
510b857f7d1e7e8d38912890536342dd5dd647ddLennart Poetteringstatic int stdout_stream_log(StdoutStream *s, const char *p) {
510b857f7d1e7e8d38912890536342dd5dd647ddLennart Poettering _cleanup_free_ char *message = NULL, *syslog_priority = NULL, *syslog_facility = NULL, *syslog_identifier = NULL;
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer unsigned n = 0;
510b857f7d1e7e8d38912890536342dd5dd647ddLennart Poettering syslog_parse_priority((char**) &p, &priority, false);
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer if (s->forward_to_syslog || s->server->forward_to_syslog)
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer server_forward_syslog(s->server, syslog_fixup_facility(priority), s->identifier, p, &s->ucred, NULL);
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer if (s->forward_to_kmsg || s->server->forward_to_kmsg)
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer server_forward_kmsg(s->server, priority, s->identifier, p, &s->ucred);
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer if (s->forward_to_console || s->server->forward_to_console)
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer server_forward_console(s->server, priority, s->identifier, p, &s->ucred);
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer IOVEC_SET_STRING(iovec[n++], "_TRANSPORT=stdout");
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0)
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer IOVEC_SET_STRING(iovec[n++], syslog_priority);
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0)
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer IOVEC_SET_STRING(iovec[n++], syslog_facility);
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer syslog_identifier = strappend("SYSLOG_IDENTIFIER=", s->identifier);
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer IOVEC_SET_STRING(iovec[n++], syslog_identifier);
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek label = (char*) s->security_context;
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer label_len = strlen((char*) s->security_context);
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer server_dispatch_message(s->server, iovec, n, ELEMENTSOF(iovec), &s->ucred, NULL, label, label_len, s->unit_id, priority, 0);
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmekstatic int stdout_stream_line(StdoutStream *s, char *p) {
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer if (r < 0 || s->priority < 0 || s->priority > 999) {
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer log_warning("Failed to parse log priority line.");
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer log_warning("Failed to parse level prefix line.");
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek s->state = STDOUT_STREAM_FORWARD_TO_SYSLOG;
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek case STDOUT_STREAM_FORWARD_TO_SYSLOG:
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek log_warning("Failed to parse forward to syslog line.");
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek s->state = STDOUT_STREAM_FORWARD_TO_KMSG;
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek case STDOUT_STREAM_FORWARD_TO_KMSG:
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek log_warning("Failed to parse copy to kmsg line.");
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek s->state = STDOUT_STREAM_FORWARD_TO_CONSOLE;
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek case STDOUT_STREAM_FORWARD_TO_CONSOLE:
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek log_warning("Failed to parse copy to console line.");
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek s->state = STDOUT_STREAM_RUNNING;
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek assert_not_reached("Unknown stream state");
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmekstatic int stdout_stream_scan(StdoutStream *s, bool force_flush) {
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek end = memchr(p, '\n', remaining);
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek else if (remaining >= sizeof(s->buffer) - 1) {
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek end = p + sizeof(s->buffer) - 1;
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek if (force_flush && remaining > 0) {
5cb24cd32bce87cc618b857c059f1187e03d2b24Zbigniew Jędrzejewski-Szmek memmove(s->buffer, p, remaining);
143bfdaf0b890fa7acadf02d1eafacaef1b696bdHolger Hans Peter Freyther l = read(s->fd, s->buffer+s->length, sizeof(s->buffer)-1-s->length);
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer log_warning("Failed to read from stream: %m");
7a050b54b7c78717d5efb2e380623ccad2a70148Marius Vollmer if (l == 0) {
r = stdout_stream_scan(s, true);
s->length += l;
r = stdout_stream_scan(s, false);
assert(s);
if (s->server) {
if (s->fd >= 0) {
if (s->server)
#ifdef HAVE_SELINUX
if (s->security_context)
free(s);
int fd, r;
assert(s);
if (fd < 0) {
return -errno;
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;