Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.sbin/syslogd add support for outputting to FIFO's (Antho...



details:   https://anonhg.NetBSD.org/src/rev/623d1367f79c
branches:  trunk
changeset: 791234:623d1367f79c
user:      christos <christos%NetBSD.org@localhost>
date:      Sat Nov 09 19:00:18 2013 +0000

description:
add support for outputting to FIFO's (Anthony Mallet)

diffstat:

 usr.sbin/syslogd/syslog.conf.5 |   8 ++-
 usr.sbin/syslogd/syslogd.c     |  85 +++++++++++++++++++++++++++++++++++++++--
 2 files changed, 85 insertions(+), 8 deletions(-)

diffs (214 lines):

diff -r 5143168cb933 -r 623d1367f79c usr.sbin/syslogd/syslog.conf.5
--- a/usr.sbin/syslogd/syslog.conf.5    Sat Nov 09 18:58:22 2013 +0000
+++ b/usr.sbin/syslogd/syslog.conf.5    Sat Nov 09 19:00:18 2013 +0000
@@ -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 @@
 .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
diff -r 5143168cb933 -r 623d1367f79c usr.sbin/syslogd/syslogd.c
--- a/usr.sbin/syslogd/syslogd.c        Sat Nov 09 18:58:22 2013 +0000
+++ b/usr.sbin/syslogd/syslogd.c        Sat Nov 09 19:00:18 2013 +0000
@@ -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 @@
 #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 @@
  * 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 @@
 #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 @@
        {"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 @@
            || (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 @@
        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 @@
                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 @@
                }
                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 @@
                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 @@
 #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 @@
                        case F_FILE:
                        case F_TTY:
                        case F_CONSOLE:
+                       case F_FIFO:
                                printf("%s", f->f_un.f_fname);
                                break;
 
@@ -3622,6 +3687,7 @@
        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 @@
                        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 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) {



Home | Main Index | Thread Index | Old Index