Hi List!

There seems to be a fair bit of code in our tree which outputs to both
syslog and stdout/stderr via printf/perror/warnx, etc.
I'll make the assumption that is because syslog output via LOG_PERROR
isn't pretty. It also only goes to stderr.
Also, there are cases where you want to run a daemon in the foreground
for debugging and as such you don't really want messages to appear in
the system logs.

To help reduce this duplication of output function and make our binaries
smaller, I propose extend syslog as follows:
   LOG_POUT  - output only the formattted message to stdout
               if pri > LOG_ERR, otherwise stderr
   LOG_NOLOG - don't log to syslog or console
               assume LOG_PERROR or LOG_POUT is present

Comments welcome, sample patch attached for review.

Roy
Index: lib/libc/gen/syslog.3
===================================================================
RCS file: /cvsroot/src/lib/libc/gen/syslog.3,v
retrieving revision 1.29
diff -p -u -r1.29 syslog.3
--- lib/libc/gen/syslog.3       25 Jul 2011 19:42:50 -0000      1.29
+++ lib/libc/gen/syslog.3       6 Oct 2016 14:32:42 -0000
@@ -30,7 +30,7 @@
 .\"
 .\"     @(#)syslog.3   8.1 (Berkeley) 6/4/93
 .\"
-.Dd May 3, 2010
+.Dd October 6, 2016
 .Dt SYSLOG 3
 .Os
 .Sh NAME
@@ -302,6 +302,18 @@ Log the process id with each message: us
 instantiations of daemons.
 (This PID is placed within brackets
 between the ident and the message.)
+.It Dv LOG_POUT
+Write the message to standard output if priority is greater than
+.Dv LOG_ERR ,
+otherwise standard error.
+The message is also written to the system log.
+.It Dv LOG_NOLOG
+The message is not written to the system log.
+Either
+.Dv LOG_PERROR
+or
+.Dv LOG_POUT
+should be set.
 .El
 .Pp
 The
@@ -484,6 +496,10 @@ The async-signal-safe functions appeared
 .Nx 4.0 .
 The syslog-protocol functions appeared in
 .Nx 5.0 .
+The
+.Fa logopt
+options LOG_POUT and LOG_NOLOG appeared in
+.Nx 8.0 .
 .Sh CAVEATS
 It is important never to pass a string with user-supplied data as a
 format without using
Index: lib/libc/gen/syslog.c
===================================================================
RCS file: /cvsroot/src/lib/libc/gen/syslog.c,v
retrieving revision 1.55
diff -p -u -r1.55 syslog.c
--- lib/libc/gen/syslog.c       26 Oct 2015 11:44:30 -0000      1.55
+++ lib/libc/gen/syslog.c       6 Oct 2016 14:32:43 -0000
@@ -230,7 +230,7 @@ vsyslogp_r(int pri, struct syslog_data *
 
        pri &= ~LOG_SIGNAL_SAFE;
 
-#define INTERNALLOG    LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID
+#define INTERNALLOG    LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID|LOG_POUT|LOG_NOLOG
        /* Check for invalid bits. */
        if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) {
                syslog_r(INTERNALLOG | signal_safe, data,
@@ -317,7 +317,7 @@ vsyslogp_r(int pri, struct syslog_data *
        if (data == &sdata)
                mutex_unlock(&syslog_mutex);
 
-       if (data->log_stat & (LOG_PERROR|LOG_CONS)) {
+       if (data->log_stat & (LOG_PERROR|LOG_POUT|LOG_CONS)) {
                iovcnt = 0;
                iov[iovcnt].iov_base = p;
                iov[iovcnt].iov_len = prlen - 1;
@@ -362,7 +362,7 @@ vsyslogp_r(int pri, struct syslog_data *
        } else
                strlcat(fmt_cat, "-", FMT_LEN);
 
-       if (data->log_stat & (LOG_PERROR|LOG_CONS))
+       if (data->log_stat & (LOG_PERROR|LOG_POUT|LOG_CONS))
                msgsdlen = strlen(fmt_cat) + 1;
        else
                msgsdlen = 0;   /* XXX: GCC */
@@ -409,7 +409,7 @@ vsyslogp_r(int pri, struct syslog_data *
        else
                prlen = vsnprintf(p, tbuf_left, fmt_cpy, ap);
 
-       if (data->log_stat & (LOG_PERROR|LOG_CONS)) {
+       if (data->log_stat & (LOG_PERROR|LOG_POUT|LOG_CONS)) {
                iov[iovcnt].iov_base = p + msgsdlen;
                iov[iovcnt].iov_len = prlen - msgsdlen;
                iovcnt++;
@@ -418,13 +418,28 @@ vsyslogp_r(int pri, struct syslog_data *
        DEC();
        cnt = p - tbuf;
 
-       /* Output to stderr if requested. */
-       if (data->log_stat & LOG_PERROR) {
+       /* Output if requested. */
+       if (data->log_stat & LOG_POUT) {
+               /* Only output the message. */
+               struct iovec oiov[2];
+               int f;
+
+               oiov[0] = iov[iovcnt - 1];
+               oiov[1].iov_base = __UNCONST(CRLF + 1);
+               oiov[1].iov_len = 1;
+
+               f = LOG_PRI(pri) <= LOG_ERR ? STDERR_FILENO : STDOUT_FILENO;
+               (void)writev(f, oiov, 2);
+       } else if (data->log_stat & LOG_PERROR) {
+               /* Output program[pid] and the message. */
                iov[iovcnt].iov_base = __UNCONST(CRLF + 1);
                iov[iovcnt].iov_len = 1;
                (void)writev(STDERR_FILENO, iov, iovcnt + 1);
        }
 
+       if (data->log_stat & LOG_NOLOG)
+               goto out;
+
        /* Get connected, output the message to the local logger. */
        if (data == &sdata)
                mutex_lock(&syslog_mutex);
@@ -465,6 +480,7 @@ vsyslogp_r(int pri, struct syslog_data *
                (void)close(fd);
        }
 
+out:
        if (data == &sdata)
                mutex_unlock(&syslog_mutex);
 
Index: sys/sys/syslog.h
===================================================================
RCS file: /cvsroot/src/sys/sys/syslog.h,v
retrieving revision 1.38
diff -p -u -r1.38 syslog.h
--- sys/sys/syslog.h    15 Oct 2015 06:15:22 -0000      1.38
+++ sys/sys/syslog.h    6 Oct 2016 14:32:43 -0000
@@ -168,6 +168,8 @@ CODE facilitynames[] = {
 #define        LOG_NDELAY      0x08    /* don't delay open */
 #define        LOG_NOWAIT      0x10    /* don't wait for console forks: 
DEPRECATED */
 #define        LOG_PERROR      0x20    /* log to stderr as well */
+#define        LOG_POUT        0x40    /* log to stdout or stderr if >=LOG_ERR 
*/
+#define        LOG_NOLOG       0x80    /* don't log - needs LOG_PERROR or 
LOG_POUT */
 
 #ifndef _KERNEL
 

Reply via email to