Module Name: src Committed By: christos Date: Sat Nov 9 19:00:18 UTC 2013
Modified Files: src/usr.sbin/syslogd: syslog.conf.5 syslogd.c Log Message: add support for outputting to FIFO's (Anthony Mallet) To generate a diff of this commit: cvs rdiff -u -r1.19 -r1.20 src/usr.sbin/syslogd/syslog.conf.5 cvs rdiff -u -r1.116 -r1.117 src/usr.sbin/syslogd/syslogd.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.sbin/syslogd/syslog.conf.5 diff -u src/usr.sbin/syslogd/syslog.conf.5:1.19 src/usr.sbin/syslogd/syslog.conf.5:1.20 --- src/usr.sbin/syslogd/syslog.conf.5:1.19 Fri Oct 5 12:15:45 2012 +++ src/usr.sbin/syslogd/syslog.conf.5 Sat Nov 9 14:00:18 2013 @@ -1,4 +1,4 @@ -.\" $NetBSD: syslog.conf.5,v 1.19 2012/10/05 16:15:45 msaitoh Exp $ +.\" $NetBSD: syslog.conf.5,v 1.20 2013/11/09 19:00:18 christos Exp $ .\" .\" Copyright (c) 1990, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -286,7 +286,11 @@ There are five forms: .Bl -bullet .It A pathname (beginning with a leading slash). -Selected messages are appended to the file. +Selected messages are appended to the file, unless +pathname points to an existing FIFO special file. +.Xr syslogd 8 +treats FIFO specially by opening them in non-blocking mode and +discarding messages sent when no reader is listening on the other side. .Pp To ensure that kernel messages are written to disk promptly, .Xr syslogd 8 Index: src/usr.sbin/syslogd/syslogd.c diff -u src/usr.sbin/syslogd/syslogd.c:1.116 src/usr.sbin/syslogd/syslogd.c:1.117 --- src/usr.sbin/syslogd/syslogd.c:1.116 Sat Nov 9 13:58:22 2013 +++ src/usr.sbin/syslogd/syslogd.c Sat Nov 9 14:00:18 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: syslogd.c,v 1.116 2013/11/09 18:58:22 christos Exp $ */ +/* $NetBSD: syslogd.c,v 1.117 2013/11/09 19:00:18 christos Exp $ */ /* * Copyright (c) 1983, 1988, 1993, 1994 @@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 19 #if 0 static char sccsid[] = "@(#)syslogd.c 8.3 (Berkeley) 4/4/94"; #else -__RCSID("$NetBSD: syslogd.c,v 1.116 2013/11/09 18:58:22 christos Exp $"); +__RCSID("$NetBSD: syslogd.c,v 1.117 2013/11/09 19:00:18 christos Exp $"); #endif #endif /* not lint */ @@ -70,6 +70,7 @@ __RCSID("$NetBSD: syslogd.c,v 1.116 2013 * TLS, syslog-protocol, and syslog-sign code by Martin Schuette. */ #define SYSLOG_NAMES +#include <sys/stat.h> #include <poll.h> #include "syslogd.h" #include "extern.h" @@ -133,7 +134,8 @@ int repeatinterval[] = { 30, 120, 600 }; #define F_USERS 5 /* list of users */ #define F_WALL 6 /* everyone logged on */ #define F_PIPE 7 /* pipe to program */ -#define F_TLS 8 +#define F_FIFO 8 /* mkfifo(2) file */ +#define F_TLS 9 struct TypeInfo { const char *name; @@ -155,6 +157,7 @@ struct TypeInfo { {"USERS", NULL, "0", NULL, "0", 0, 0, 1024}, {"WALL", NULL, "0", NULL, "0", 0, 0, 1024}, {"PIPE", NULL, "1024", NULL, "1M", 0, 0, 16384}, + {"FIFO", NULL, "1024", NULL, "1M", 0, 0, 16384}, #ifndef DISABLE_TLS {"TLS", NULL, "-1", NULL, "16M", 0, 0, 16384} #endif /* !DISABLE_TLS */ @@ -2187,7 +2190,8 @@ fprintlog(struct filed *f, struct buf_ms || (f->f_type == F_TTY) || (f->f_type == F_CONSOLE) || (f->f_type == F_USERS) - || (f->f_type == F_WALL))) { + || (f->f_type == F_WALL) + || (f->f_type == F_FIFO))) { DELREF(buffer); return; } @@ -2196,7 +2200,8 @@ fprintlog(struct filed *f, struct buf_ms if (qentry && (f->f_type != F_TLS) && (f->f_type != F_PIPE) - && (f->f_type != F_FILE)) { + && (f->f_type != F_FILE) + && (f->f_type != F_FIFO)) { errno = 0; logerror("Warning: unexpected message type %d in buffer", f->f_type); @@ -2253,6 +2258,7 @@ fprintlog(struct filed *f, struct buf_ms len = linelen - tlsprefixlen; break; case F_PIPE: + case F_FIFO: case F_FILE: /* fallthrough */ if (f->f_flags & FFLAG_FULL) { v->iov_base = line + tlsprefixlen; @@ -2453,6 +2459,60 @@ fprintlog(struct filed *f, struct buf_ms } break; + case F_FIFO: + DPRINTF(D_MISC, "Logging to %s %s\n", + TypeInfo[f->f_type].name, f->f_un.f_fname); + if (f->f_file < 0) { + f->f_file = + open(f->f_un.f_fname, O_WRONLY|O_NONBLOCK, 0); + e = errno; + if (f->f_file < 0 && e == ENXIO) { + /* Drop messages with no reader */ + if (qentry) + message_queue_remove(f, qentry); + break; + } + } + + if (f->f_file >= 0 && writev(f->f_file, iov, v - iov) < 0) { + e = errno; + + /* Enqueue if the fifo buffer is full */ + if (e == EAGAIN) { + if (f->f_lasterror != e) + logerror("%s", f->f_un.f_fname); + f->f_lasterror = e; + error = true; /* enqueue on return */ + break; + } + + close(f->f_file); + f->f_file = -1; + + /* Drop messages with no reader */ + if (e == EPIPE) { + if (qentry) + message_queue_remove(f, qentry); + break; + } + } + + if (f->f_file < 0) { + f->f_type = F_UNUSED; + errno = e; + f->f_lasterror = e; + logerror("%s", f->f_un.f_fname); + message_queue_freeall(f); + break; + } + + f->f_lasterror = 0; + if (!qentry) /* prevent recursion (see comment for F_FILE) */ + SEND_QUEUE(f); + if (qentry) /* sent buffered msg */ + message_queue_remove(f, qentry); + break; + case F_USERS: case F_WALL: DPRINTF(D_MISC, "Logging to %s\n", TypeInfo[f->f_type].name); @@ -2879,7 +2939,9 @@ die(int fd, short event, void *ev) case F_FILE: case F_TTY: case F_CONSOLE: - (void)close(f->f_file); + case F_FIFO: + if (f->f_file >= 0) + (void)close(f->f_file); break; case F_PIPE: if (f->f_un.f_pipe.f_pid > 0) { @@ -3052,8 +3114,10 @@ read_config_file(FILE *cf, struct filed #endif /* !DISABLE_TLS */ {"file_queue_length", &TypeInfo[F_FILE].queue_length_string}, {"pipe_queue_length", &TypeInfo[F_PIPE].queue_length_string}, + {"fifo_queue_length", &TypeInfo[F_FIFO].queue_length_string}, {"file_queue_size", &TypeInfo[F_FILE].queue_size_string}, {"pipe_queue_size", &TypeInfo[F_PIPE].queue_size_string}, + {"fifo_queue_size", &TypeInfo[F_FIFO].queue_size_string}, #ifndef DISABLE_SIGN /* syslog-sign setting */ {"sign_sg", &sign_sg_str}, @@ -3473,6 +3537,7 @@ init(int fd, short event, void *ev) case F_FILE: case F_TTY: case F_CONSOLE: + case F_FIFO: printf("%s", f->f_un.f_fname); break; @@ -3622,6 +3687,7 @@ cfline(size_t linenum, const char *line, const char *p, *q; char *bp; char buf[MAXLINE]; + struct stat sb; DPRINTF((D_CALL|D_PARSE), "cfline(%zu, \"%s\", f, \"%s\", \"%s\")\n", @@ -3832,6 +3898,12 @@ cfline(size_t linenum, const char *line, f->f_flags |= FFLAG_SIGN; #endif /* !DISABLE_SIGN */ (void)strlcpy(f->f_un.f_fname, p, sizeof(f->f_un.f_fname)); + if (!stat(p, &sb) && S_ISFIFO(sb.st_mode)) { + f->f_file = -1; + f->f_type = F_FIFO; + break; + } + if ((f->f_file = open(p, O_WRONLY|O_APPEND, 0)) < 0) { f->f_type = F_UNUSED; logerror("%s", p); @@ -4312,6 +4384,7 @@ find_qentry_to_delete(const struct buf_q /* find elements to delete */ if (strategy == PURGE_BY_PRIORITY) { qentry_tmp = qentry_static; + if (!qentry_tmp) return NULL; while ((qentry_tmp = STAILQ_NEXT(qentry_tmp, entries)) != NULL) { if (LOG_PRI(qentry_tmp->msg->pri) == pri) {