Do some cleanup in syslogd ttymsg(). Add a debug message when the
authorbluhm <bluhm@openbsd.org>
Wed, 21 Oct 2015 14:03:07 +0000 (14:03 +0000)
committerbluhm <bluhm@openbsd.org>
Wed, 21 Oct 2015 14:03:07 +0000 (14:03 +0000)
syslogd child calls fork(2) to delay blocked output.
OK benno@

usr.sbin/syslogd/syslogd.c
usr.sbin/syslogd/syslogd.h
usr.sbin/syslogd/ttymsg.c

index 6f68dbd..4bde888 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: syslogd.c,v 1.198 2015/10/15 20:26:47 bluhm Exp $     */
+/*     $OpenBSD: syslogd.c,v 1.199 2015/10/21 14:03:07 bluhm Exp $     */
 
 /*
  * Copyright (c) 1983, 1988, 1993, 1994
@@ -64,8 +64,6 @@
 #define DEFUPRI                (LOG_USER|LOG_NOTICE)
 #define DEFSPRI                (LOG_KERN|LOG_CRIT)
 #define TIMERINTVL     30              /* interval for checking flush, mark */
-#define TTYMSGTIME     1               /* timeout passed to ttymsg */
-#define ERRBUFSIZE     256
 
 #include <sys/ioctl.h>
 #include <sys/stat.h>
@@ -332,7 +330,6 @@ void        logmsg(int, char *, char *, int);
 struct filed *find_dup(struct filed *);
 void   printline(char *, char *);
 void   printsys(char *);
-char   *ttymsg(struct iovec *, int, char *, int);
 void   usage(void);
 void   wallmsg(struct filed *, struct iovec *);
 int    loghost_parse(char *, char **, char **, char **);
@@ -1926,7 +1923,7 @@ void
 wallmsg(struct filed *f, struct iovec *iov)
 {
        struct utmp ut;
-       char line[sizeof(ut.ut_line) + 1], *p;
+       char utline[sizeof(ut.ut_line) + 1], *p;
        static int reenter;                     /* avoid calling ourselves */
        FILE *uf;
        int i;
@@ -1942,10 +1939,10 @@ wallmsg(struct filed *f, struct iovec *iov)
                if (ut.ut_name[0] == '\0')
                        continue;
                /* must use strncpy since ut_* may not be NUL terminated */
-               strncpy(line, ut.ut_line, sizeof(line) - 1);
-               line[sizeof(line) - 1] = '\0';
+               strncpy(utline, ut.ut_line, sizeof(utline) - 1);
+               utline[sizeof(utline) - 1] = '\0';
                if (f->f_type == F_WALL) {
-                       if ((p = ttymsg(iov, 6, line, TTYMSGTIME)) != NULL)
+                       if ((p = ttymsg(iov, 6, utline)) != NULL)
                                logerrorx(p);
                        continue;
                }
@@ -1955,7 +1952,7 @@ wallmsg(struct filed *f, struct iovec *iov)
                                break;
                        if (!strncmp(f->f_un.f_uname[i], ut.ut_name,
                            UT_NAMESIZE)) {
-                               if ((p = ttymsg(iov, 6, line, TTYMSGTIME))
+                               if ((p = ttymsg(iov, 6, utline))
                                    != NULL)
                                        logerrorx(p);
                                break;
index 37fd928..bf90882 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: syslogd.h,v 1.21 2015/10/15 20:26:47 bluhm Exp $ */
+/*     $OpenBSD: syslogd.h,v 1.22 2015/10/21 14:03:07 bluhm Exp $ */
 
 /*
  * Copyright (c) 2003 Anil Madhavapeddy <anil@recoil.org>
@@ -32,7 +32,8 @@ int   priv_getaddrinfo(char *, char *, char *, struct sockaddr *, size_t);
 int   priv_getnameinfo(struct sockaddr *, socklen_t, char *, size_t);
 
 /* Terminal message */
-char *ttymsg(struct iovec *, int, char *, int);
+#define TTYMSGTIME     1               /* timeout used by ttymsg */
+char *ttymsg(struct iovec *, int, char *);
 
 /* File descriptor send/recv */
 void send_fd(int, int);
@@ -46,6 +47,7 @@ extern char *path_ctlsock;
 extern int fd_ctlsock, fd_ctlconn, fd_klog, fd_sendsys;
 extern int fd_udp, fd_udp6, fd_bind, fd_listen, fd_tls, fd_unix[MAXUNIX];
 
+#define ERRBUFSIZE     256
 void logdebug(const char *, ...) __attribute__((__format__ (printf, 1, 2)));
 extern int Debug;
 extern int Startup;
index 2e23d8b..a18ef8f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ttymsg.c,v 1.7 2015/07/06 16:12:16 millert Exp $      */
+/*     $OpenBSD: ttymsg.c,v 1.8 2015/10/21 14:03:07 bluhm Exp $        */
 /*     $NetBSD: ttymsg.c,v 1.3 1994/11/17 07:17:55 jtc Exp $   */
 
 /*
 #include <sys/param.h> /* nitems */
 #include <sys/stat.h>
 
-#include <signal.h>
-#include <fcntl.h>
 #include <dirent.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <paths.h>
-#include <unistd.h>
+#include <signal.h>
 #include <stdio.h>
-#include <string.h>
 #include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
 
 #include "syslogd.h"
 
 /*
  * Display the contents of a uio structure on a terminal.
- * Forks and finishes in child if write would block, waiting up to tmout
+ * Forks and finishes in child if write would block, waiting up to TTYMSGTIME
  * seconds.  Returns pointer to error string on unexpected error;
  * string is not newline-terminated.  Various "normal" errors are ignored
  * (exclusive-use, lack of permission, etc.).
  */
 char *
-ttymsg(struct iovec *iov, int iovcnt, char *line, int tmout)
+ttymsg(struct iovec *iov, int iovcnt, char *utline)
 {
        static char device[MAXNAMLEN] = _PATH_DEV;
-       static char errbuf[1024];
-       int cnt, fd, left;
+       static char ebuf[ERRBUFSIZE];
+       int cnt, fd;
+       size_t left;
        ssize_t wret;
        struct iovec localiov[6];
        int forked = 0;
@@ -69,17 +70,17 @@ ttymsg(struct iovec *iov, int iovcnt, char *line, int tmout)
        /*
         * Ignore lines that start with "ftp" or "uucp".
         */
-       if ((strncmp(line, "ftp", 3) == 0) ||
-           (strncmp(line, "uucp", 4) == 0))
+       if ((strncmp(utline, "ftp", 3) == 0) ||
+           (strncmp(utline, "uucp", 4) == 0))
                return (NULL);
 
-       (void) strlcpy(device + sizeof(_PATH_DEV) - 1, line,
+       (void) strlcpy(device + sizeof(_PATH_DEV) - 1, utline,
            sizeof(device) - (sizeof(_PATH_DEV) - 1));
        if (strchr(device + sizeof(_PATH_DEV) - 1, '/')) {
                /* A slash is an attempt to break security... */
-               (void) snprintf(errbuf, sizeof(errbuf), "'/' in \"%s\"",
+               (void) snprintf(ebuf, sizeof(ebuf), "'/' in \"%s\"",
                    device);
-               return (errbuf);
+               return (ebuf);
        }
 
        /*
@@ -89,26 +90,27 @@ ttymsg(struct iovec *iov, int iovcnt, char *line, int tmout)
        if ((fd = priv_open_tty(device)) < 0) {
                if (errno == EBUSY || errno == EACCES)
                        return (NULL);
-               (void) snprintf(errbuf, sizeof(errbuf),
+               (void) snprintf(ebuf, sizeof(ebuf),
                    "%s: %s", device, strerror(errno));
-               return (errbuf);
+               return (ebuf);
        }
 
-       for (cnt = left = 0; cnt < iovcnt; ++cnt)
+       left = 0;
+       for (cnt = 0; cnt < iovcnt; ++cnt)
                left += iov[cnt].iov_len;
 
        for (;;) {
                wret = writev(fd, iov, iovcnt);
-               if (wret >= left)
-                       break;
                if (wret >= 0) {
+                       if ((size_t)wret >= left)
+                               break;
                        left -= wret;
                        if (iov != localiov) {
                                bcopy(iov, localiov,
                                    iovcnt * sizeof(struct iovec));
                                iov = localiov;
                        }
-                       for (cnt = 0; (size_t)wret >= iov->iov_len; ++cnt) {
+                       while ((size_t)wret >= iov->iov_len) {
                                wret -= iov->iov_len;
                                ++iov;
                                --iovcnt;
@@ -127,24 +129,25 @@ ttymsg(struct iovec *iov, int iovcnt, char *line, int tmout)
                                (void) close(fd);
                                _exit(1);
                        }
+                       logdebug("ttymsg delayed write\n");
                        cpid = fork();
                        if (cpid < 0) {
-                               (void) snprintf(errbuf, sizeof(errbuf),
+                               (void) snprintf(ebuf, sizeof(ebuf),
                                    "fork: %s", strerror(errno));
                                (void) close(fd);
-                               return (errbuf);
+                               return (ebuf);
                        }
                        if (cpid) {     /* parent */
                                (void) close(fd);
                                return (NULL);
                        }
                        forked++;
-                       /* wait at most tmout seconds */
+                       /* wait at most TTYMSGTIME seconds */
                        (void) signal(SIGALRM, SIG_DFL);
                        (void) signal(SIGTERM, SIG_DFL); /* XXX */
                        (void) sigemptyset(&mask);
                        (void) sigprocmask(SIG_SETMASK, &mask, NULL);
-                       (void) alarm((u_int)tmout);
+                       (void) alarm((u_int)TTYMSGTIME);
                        (void) fcntl(fd, O_NONBLOCK, &off);
                        continue;
                }
@@ -157,9 +160,9 @@ ttymsg(struct iovec *iov, int iovcnt, char *line, int tmout)
                (void) close(fd);
                if (forked)
                        _exit(1);
-               (void) snprintf(errbuf, sizeof(errbuf),
+               (void) snprintf(ebuf, sizeof(ebuf),
                    "%s: %s", device, strerror(errno));
-               return (errbuf);
+               return (ebuf);
        }
 
        (void) close(fd);