fix syslog (corrected SIGPIPE blocking, and using dgram instead of stream)
authorRich Felker <dalias@aerifal.cx>
Wed, 13 Apr 2011 21:24:25 +0000 (17:24 -0400)
committerRich Felker <dalias@aerifal.cx>
Wed, 13 Apr 2011 21:24:25 +0000 (17:24 -0400)
it actually appears the hacks to block SIGPIPE are probably not
necessary, and potentially harmful. if i can confirm this, i'll remove
them.

src/misc/syslog.c

index 4809d2d..6fc6f4d 100644 (file)
@@ -49,7 +49,7 @@ static void __openlog(const char *ident, int opt, int facility)
 
        if (!(opt & LOG_NDELAY) || log_f) return;
 
-       fd = socket(AF_UNIX, SOCK_STREAM, 0);
+       fd = socket(AF_UNIX, SOCK_DGRAM, 0);
        fcntl(fd, F_SETFD, FD_CLOEXEC);
        if (connect(fd, (void *)&log_addr, sizeof(short) + sizeof "/dev/log") < 0)
                close(fd);
@@ -65,7 +65,7 @@ void openlog(const char *ident, int opt, int facility)
 
 void syslog(int priority, const char *message, ...)
 {
-       struct sigaction sa;
+       sigset_t set, oldset;
        va_list ap;
        char timebuf[16];
        time_t now;
@@ -83,13 +83,9 @@ void syslog(int priority, const char *message, ...)
                return;
        }
 
-       memset(&sa, 0, sizeof sa);
-       sa.sa_handler = SIG_IGN;
-       if (sigaction(SIGPIPE, &sa, &sa) < 0) {
-               // we must abandon logging or we might cause SIGPIPE
-               UNLOCK(&lock);
-               return;
-       }
+       sigemptyset(&set);
+       sigaddset(&set, SIGPIPE);
+       pthread_sigmask(SIG_BLOCK, &set, &oldset);
 
        now = time(NULL);
        gmtime_r(&now, &tm);
@@ -109,7 +105,9 @@ void syslog(int priority, const char *message, ...)
        // Note: LOG_CONS is not supported because it is annoying!!
        // syslogd will send messages to console if it deems them appropriate!
 
-       sigaction(SIGPIPE, &sa, NULL);
+       /* Clear any possible SIGPIPE generated by the socket write. */
+       sigtimedwait(&set, 0, (struct timespec [1]){0}) || (perror("x"),1);
+       pthread_sigmask(SIG_SETMASK, &oldset, 0);
 
        UNLOCK(&lock);
 }