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) {

Reply via email to