logger.c revision addab137cd8d318e4f543ca56018ee23d51aaca9
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering This file is part of systemd.
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering Copyright 2010 Lennart Poettering
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering systemd is free software; you can redistribute it and/or modify it
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering under the terms of the GNU General Public License as published by
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering the Free Software Foundation; either version 2 of the License, or
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering (at your option) any later version.
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering systemd is distributed in the hope that it will be useful, but
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering General Public License for more details.
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering You should have received a copy of the GNU General Public License
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poetteringtypedef struct Server {
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poetteringstatic int stream_log(Stream *s, char *p, usec_t ts) {
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering char header_priority[16], header_time[64], header_pid[16];
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering p[0] == '<' &&
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering /* Detected priority prefix */
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering priority = LOG_MAKEPRI(LOG_FAC(priority), (p[1] - '0'));
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering * The format glibc uses to talk to the syslog daemon is:
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering * <priority>time process[pid]: msg
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering * The format the kernel uses is:
e0e009c067aa7237f9683c46e5845bbb11ec67c2Jan Engelhardt * <priority>msg\n
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering * We extend the latter to include the process name and pid.
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering snprintf(header_priority, sizeof(header_priority), "<%i>",
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering s->target == STREAM_SYSLOG ? priority : LOG_PRI(priority));
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering if (strftime(header_time, sizeof(header_time), "%h %e %T ", tm) <= 0)
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering snprintf(header_pid, sizeof(header_pid), "[%lu]: ", (unsigned long) s->pid);
99e0f83e0bcc54dbc2b3a4f3fdd15fcd3033b21eLennart Poettering IOVEC_SET_STRING(iovec[0], header_priority);
} control;
return -errno;
return -errno;
assert(s);
assert(p);
p = strstrip(p);
switch (s->state) {
case STREAM_TARGET:
return -EPERM;
return -EBADMSG;
case STREAM_PRIORITY:
if (s->priority < 0) {
return -ERANGE;
case STREAM_PROCESS:
return -ENOMEM;
case STREAM_PREFIX:
if ((r = parse_boolean(p)) < 0)
s->prefix = r;
case STREAM_RUNNING:
assert(s);
p = s->buffer;
char *newline;
*newline = 0;
if (p > s->buffer) {
ssize_t l;
assert(s);
s->length += l;
assert(s);
if (s->server) {
if (s->fd >= 0) {
if (s->server)
free(s);
int fd;
assert(s);
return -errno;
return -ENOMEM;
r = -errno;
goto fail;
r = -errno;
goto fail;
r = -errno;
goto fail;
s->n_streams ++;
fail:
assert(s);
while (s->streams)
for (i = 0; i < s->n_server_fd; i++)
if (s->syslog_fd >= 0)
if (s->epoll_fd >= 0)
if (s->kmsg_fd >= 0)
} sa;
assert(s);
zero(*s);
r = -errno;
goto fail;
for (i = 0; i < n_sockets; i++) {
int fd;
goto fail;
r = -EINVAL;
goto fail;
r = -errno;
goto fail;
r = -errno;
goto fail;
r = -errno;
goto fail;
fail:
server_done(s);
assert(s);
return -EIO;
log_open();
if ((n = sd_listen_fds(true)) < 0) {
if (n <= 0 || n > SERVER_FD_MAX) {
sd_notify(false,
goto fail;
goto fail;
fail:
sd_notify(false,