syslogd: make "-O -" log to stdout
authorDenys Vlasenko <vda.linux@googlemail.com>
Wed, 2 Jul 2014 13:21:30 +0000 (15:21 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Wed, 2 Jul 2014 13:21:30 +0000 (15:21 +0200)
function                                             old     new   delta
packed_usage                                       29871   29908     +37
log_locally                                          404     440     +36
syslogd_main                                        1966    1956     -10
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/1 up/down: 73/-10)             Total: 63 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
sysklogd/syslogd.c

index f75851085ce1e74c9058112b3f249e1dd777dddc..d80447bd73ee669a108b894f47db7b33bb0c19da 100644 (file)
 //usage:       "(this version of syslogd ignores /etc/syslog.conf)\n"
 //usage:       )
 //usage:     "\n       -n              Run in foreground"
-//usage:     "\n       -O FILE         Log to FILE (default:/var/log/messages)"
-//usage:     "\n       -l N            Log only messages more urgent than prio N (1-8)"
-//usage:     "\n       -S              Smaller output"
-//usage:       IF_FEATURE_ROTATE_LOGFILE(
-//usage:     "\n       -s SIZE         Max size (KB) before rotation (default:200KB, 0=off)"
-//usage:     "\n       -b N            N rotated logs to keep (default:1, max=99, 0=purge)"
-//usage:       )
 //usage:       IF_FEATURE_REMOTE_LOG(
 //usage:     "\n       -R HOST[:PORT]  Log to HOST:PORT (default PORT:514)"
 //usage:     "\n       -L              Log locally and via network (default is network only if -R)"
 //usage:       )
-//usage:       IF_FEATURE_SYSLOGD_DUP(
-//usage:     "\n       -D              Drop duplicates"
-//usage:       )
 //usage:       IF_FEATURE_IPC_SYSLOG(
 /* NB: -Csize shouldn't have space (because size is optional) */
 //usage:     "\n       -C[size_kb]     Log to shared mem buffer (use logread to read it)"
 //usage:       )
+//usage:       IF_FEATURE_KMSG_SYSLOG(
+//usage:     "\n       -K              Log to kernel printk buffer (use dmesg to read it)"
+//usage:       )
+//usage:     "\n       -O FILE         Log to FILE (default:/var/log/messages, stdout if -)"
+//usage:       IF_FEATURE_ROTATE_LOGFILE(
+//usage:     "\n       -s SIZE         Max size (KB) before rotation (default:200KB, 0=off)"
+//usage:     "\n       -b N            N rotated logs to keep (default:1, max=99, 0=purge)"
+//usage:       )
+//usage:     "\n       -l N            Log only messages more urgent than prio N (1-8)"
+//usage:     "\n       -S              Smaller output"
+//usage:       IF_FEATURE_SYSLOGD_DUP(
+//usage:     "\n       -D              Drop duplicates"
+//usage:       )
 //usage:       IF_FEATURE_SYSLOGD_CFG(
 //usage:     "\n       -f FILE         Use FILE as config (default:/etc/syslog.conf)"
 //usage:       )
 /* //usage:  "\n       -m MIN          Minutes between MARK lines (default:20, 0=off)" */
-//usage:       IF_FEATURE_KMSG_SYSLOG(
-//usage:     "\n       -K              Log to kernel printk buffer (use dmesg to read it)"
-//usage:       )
 //usage:
 //usage:#define syslogd_example_usage
 //usage:       "$ syslogd -R masterlog:514\n"
@@ -585,7 +585,9 @@ static void log_locally(time_t now, char *msg, logFile_t *log_file)
 #endif
        int len = strlen(msg);
 
-       if (log_file->fd >= 0) {
+       /* fd can't be 0 (we connect fd 0 to /dev/log socket) */
+       /* fd is 1 if "-O -" is in use */
+       if (log_file->fd > 1) {
                /* Reopen log file every second. This allows admin
                 * to delete the file and not worry about restarting us.
                 * This costs almost nothing since it happens
@@ -598,29 +600,38 @@ static void log_locally(time_t now, char *msg, logFile_t *log_file)
                        close(log_file->fd);
                        goto reopen;
                }
-       } else {
+       }
+       else if (log_file->fd == 1) {
+               /* We are logging to stdout: do nothing */
+       }
+       else {
+               if (LONE_DASH(log_file->path)) {
+                       log_file->fd = 1;
+                       /* log_file->isRegular = 0; - already is */
+               } else {
  reopen:
-               log_file->fd = open(log_file->path, O_WRONLY | O_CREAT
+                       log_file->fd = open(log_file->path, O_WRONLY | O_CREAT
                                        | O_NOCTTY | O_APPEND | O_NONBLOCK,
                                        0666);
-               if (log_file->fd < 0) {
-                       /* cannot open logfile? - print to /dev/console then */
-                       int fd = device_open(DEV_CONSOLE, O_WRONLY | O_NOCTTY | O_NONBLOCK);
-                       if (fd < 0)
-                               fd = 2; /* then stderr, dammit */
-                       full_write(fd, msg, len);
-                       if (fd != 2)
-                               close(fd);
-                       return;
-               }
+                       if (log_file->fd < 0) {
+                               /* cannot open logfile? - print to /dev/console then */
+                               int fd = device_open(DEV_CONSOLE, O_WRONLY | O_NOCTTY | O_NONBLOCK);
+                               if (fd < 0)
+                                       fd = 2; /* then stderr, dammit */
+                               full_write(fd, msg, len);
+                               if (fd != 2)
+                                       close(fd);
+                               return;
+                       }
 #if ENABLE_FEATURE_ROTATE_LOGFILE
-               {
-                       struct stat statf;
-                       log_file->isRegular = (fstat(log_file->fd, &statf) == 0 && S_ISREG(statf.st_mode));
-                       /* bug (mostly harmless): can wrap around if file > 4gb */
-                       log_file->size = statf.st_size;
-               }
+                       {
+                               struct stat statf;
+                               log_file->isRegular = (fstat(log_file->fd, &statf) == 0 && S_ISREG(statf.st_mode));
+                               /* bug (mostly harmless): can wrap around if file > 4gb */
+                               log_file->size = statf.st_size;
+                       }
 #endif
+               }
        }
 
 #ifdef SYSLOGD_WRLOCK
@@ -865,7 +876,6 @@ static int try_to_resolve_remote(remoteHost_t *rh)
 static void do_syslogd(void) NORETURN;
 static void do_syslogd(void)
 {
-       int sock_fd;
 #if ENABLE_FEATURE_REMOTE_LOG
        llist_t *item;
 #endif
@@ -886,7 +896,7 @@ static void do_syslogd(void)
        signal(SIGALRM, do_mark);
        alarm(G.markInterval);
 #endif
-       sock_fd = create_socket();
+       xmove_fd(create_socket(), STDIN_FILENO);
 
        if (option_mask32 & OPT_circularlog)
                ipcsyslog_init();
@@ -907,7 +917,7 @@ static void do_syslogd(void)
                        recvbuf = G.recvbuf;
 #endif
  read_again:
-               sz = read(sock_fd, recvbuf, MAX_READ - 1);
+               sz = read(STDIN_FILENO, recvbuf, MAX_READ - 1);
                if (sz < 0) {
                        if (!bb_got_signal)
                                bb_perror_msg("read from %s", _PATH_LOG);
@@ -978,7 +988,6 @@ static void do_syslogd(void)
        } /* while (!bb_got_signal) */
 
        timestamp_and_log_internal("syslogd exiting");
-       puts("syslogd exiting");
        remove_pidfile(CONFIG_PID_FILE_PATH "/syslogd.pid");
        ipcsyslog_cleanup();
        if (option_mask32 & OPT_kmsg)