device matching against UUIDs: do not try floppies
[oweals/busybox.git] / runit / svlogd.c
index bf46ef7f825ef0311501d31a8f64f0d375c83ddb..25799f6be556a3208135a448df9b67f3c9f4ae8b 100644 (file)
@@ -25,7 +25,7 @@ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
-/* Busyboxed by Denis Vlasenko <vda.linux@googlemail.com> */
+/* Busyboxed by Denys Vlasenko <vda.linux@googlemail.com> */
 /* TODO: depends on runit_lib.c - review and reduce/eliminate */
 
 #include <sys/poll.h>
@@ -106,7 +106,7 @@ struct globals {
 #define fl_flag_0      (G.fl_flag_0     )
 #define dirn           (G.dirn          )
 #define INIT_G() do { \
-       PTR_TO_GLOBALS = xzalloc(sizeof(G)); \
+       SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
        linemax = 1000; \
        /*buflen = 1024;*/ \
        linecomplete = 1; \
@@ -145,12 +145,12 @@ static void pause_nomem(void)
 }
 static void pause1cannot(const char *m0)
 {
-       bb_perror_msg(PAUSE"cannot %s", m0);
+       bb_perror_msg(PAUSE"can't %s", m0);
        sleep(3);
 }
 static void pause2cannot(const char *m0, const char *m1)
 {
-       bb_perror_msg(PAUSE"cannot %s %s", m0, m1);
+       bb_perror_msg(PAUSE"can't %s %s", m0, m1);
        sleep(3);
 }
 
@@ -206,25 +206,33 @@ static void fmt_time_bernstein_25(char *s)
        bin2hex(s, (char*)pack, 12);
 }
 
-static unsigned processorstart(struct logdir *ld)
+static void processorstart(struct logdir *ld)
 {
+       char sv_ch;
        int pid;
 
-       if (!ld->processor) return 0;
+       if (!ld->processor) return;
        if (ld->ppid) {
                warnx("processor already running", ld->name);
-               return 0;
+               return;
        }
-       while ((pid = fork()) == -1)
-               pause2cannot("fork for processor", ld->name);
+
+       /* vfork'ed child trashes this byte, save... */
+       sv_ch = ld->fnsave[26];
+
+       while ((pid = vfork()) == -1)
+               pause2cannot("vfork for processor", ld->name);
        if (!pid) {
                char *prog[4];
                int fd;
 
                /* child */
-               signal(SIGTERM, SIG_DFL);
-               signal(SIGALRM, SIG_DFL);
-               signal(SIGHUP, SIG_DFL);
+               /* Non-ignored signals revert to SIG_DFL on exec anyway */
+               /*bb_signals(0
+                       + (1 << SIGTERM)
+                       + (1 << SIGALRM)
+                       + (1 << SIGHUP)
+                       , SIG_DFL);*/
                sig_unblock(SIGTERM);
                sig_unblock(SIGALRM);
                sig_unblock(SIGHUP);
@@ -233,13 +241,13 @@ static unsigned processorstart(struct logdir *ld)
                        bb_error_msg(INFO"processing: %s/%s", ld->name, ld->fnsave);
                fd = xopen(ld->fnsave, O_RDONLY|O_NDELAY);
                xmove_fd(fd, 0);
-               ld->fnsave[26] = 't';
+               ld->fnsave[26] = 't'; /* <- that's why we need sv_ch! */
                fd = xopen(ld->fnsave, O_WRONLY|O_NDELAY|O_TRUNC|O_CREAT);
                xmove_fd(fd, 1);
                fd = open_read("state");
                if (fd == -1) {
                        if (errno != ENOENT)
-                               bb_perror_msg_and_die(FATAL"cannot %s processor %s", "open state for", ld->name);
+                               bb_perror_msg_and_die(FATAL"can't %s processor %s", "open state for", ld->name);
                        close(xopen("state", O_WRONLY|O_NDELAY|O_TRUNC|O_CREAT));
                        fd = xopen("state", O_RDONLY|O_NDELAY);
                }
@@ -252,11 +260,11 @@ static unsigned processorstart(struct logdir *ld)
                prog[1] = (char*)"-c";
                prog[2] = ld->processor;
                prog[3] = NULL;
-               execve("/bin/sh", prog, environ);
-               bb_perror_msg_and_die(FATAL"cannot %s processor %s", "run", ld->name);
+               execv("/bin/sh", prog);
+               bb_perror_msg_and_die(FATAL"can't %s processor %s", "run", ld->name);
        }
+       ld->fnsave[26] = sv_ch; /* ...restore */
        ld->ppid = pid;
-       return 1;
 }
 
 static unsigned processorstop(struct logdir *ld)
@@ -265,7 +273,7 @@ static unsigned processorstop(struct logdir *ld)
 
        if (ld->ppid) {
                sig_unblock(SIGHUP);
-               while (wait_pid(&wstat, ld->ppid) == -1)
+               while (safe_waitpid(ld->ppid, &wstat, 0) == -1)
                        pause2cannot("wait for processor", ld->name);
                sig_block(SIGHUP);
                ld->ppid = 0;
@@ -273,7 +281,7 @@ static unsigned processorstop(struct logdir *ld)
        if (ld->fddir == -1) return 1;
        while (fchdir(ld->fddir) == -1)
                pause2cannot("change directory, want processor", ld->name);
-       if (wait_exitcode(wstat) != 0) {
+       if (WEXITSTATUS(wstat) != 0) {
                warnx("processor failed, restart", ld->name);
                ld->fnsave[26] = 't';
                unlink(ld->fnsave);
@@ -293,7 +301,7 @@ static unsigned processorstop(struct logdir *ld)
                pause2cannot("set mode of processed", ld->name);
        ld->fnsave[26] = 'u';
        if (unlink(ld->fnsave) == -1)
-               bb_error_msg(WARNING"cannot unlink: %s/%s", ld->name, ld->fnsave);
+               bb_error_msg(WARNING"can't unlink: %s/%s", ld->name, ld->fnsave);
        while (rename("newstate", "state") == -1)
                pause2cannot("rename state", ld->name);
        if (verbose)
@@ -318,7 +326,7 @@ static void rmoldest(struct logdir *ld)
                if ((f->d_name[0] == '@') && (strlen(f->d_name) == 27)) {
                        if (f->d_name[26] == 't') {
                                if (unlink(f->d_name) == -1)
-                                       warn2("cannot unlink processor leftover", f->d_name);
+                                       warn2("can't unlink processor leftover", f->d_name);
                        } else {
                                ++n;
                                if (strcmp(f->d_name, oldest) < 0)
@@ -328,14 +336,14 @@ static void rmoldest(struct logdir *ld)
                }
        }
        if (errno)
-               warn2("cannot read directory", ld->name);
+               warn2("can't read directory", ld->name);
        closedir(d);
 
        if (ld->nmax && (n > ld->nmax)) {
                if (verbose)
                        bb_error_msg(INFO"delete: %s/%s", ld->name, oldest);
                if ((*oldest == '@') && (unlink(oldest) == -1))
-                       warn2("cannot unlink oldest logfile", ld->name);
+                       warn2("can't unlink oldest logfile", ld->name);
        }
 }
 
@@ -444,7 +452,7 @@ static int buffer_pwrite(int n, char *s, unsigned len)
                                        if (strcmp(f->d_name, oldest) < 0)
                                                memcpy(oldest, f->d_name, 27);
                                }
-                       if (errno) warn2("cannot read directory, want remove old logfile",
+                       if (errno) warn2("can't read directory, want remove old logfile",
                                        ld->name);
                        closedir(d);
                        errno = ENOSPC;
@@ -454,7 +462,7 @@ static int buffer_pwrite(int n, char *s, unsigned len)
                                                        ld->name, oldest);
                                        errno = 0;
                                        if (unlink(oldest) == -1) {
-                                               warn2("cannot unlink oldest logfile", ld->name);
+                                               warn2("can't unlink oldest logfile", ld->name);
                                                errno = ENOSPC;
                                        }
                                        while (fchdir(fdwdir) == -1)
@@ -511,13 +519,13 @@ static unsigned logdir_open(struct logdir *ld, const char *fn)
 
        ld->fddir = open(fn, O_RDONLY|O_NDELAY);
        if (ld->fddir == -1) {
-               warn2("cannot open log directory", (char*)fn);
+               warn2("can't open log directory", (char*)fn);
                return 0;
        }
        close_on_exec_on(ld->fddir);
        if (fchdir(ld->fddir) == -1) {
                logdir_close(ld);
-               warn2("cannot change directory", (char*)fn);
+               warn2("can't change directory", (char*)fn);
                return 0;
        }
        ld->fdlock = open("lock", O_WRONLY|O_NDELAY|O_APPEND|O_CREAT, 0600);
@@ -525,7 +533,7 @@ static unsigned logdir_open(struct logdir *ld, const char *fn)
         || (lock_exnb(ld->fdlock) == -1)
        ) {
                logdir_close(ld);
-               warn2("cannot lock directory", (char*)fn);
+               warn2("can't lock directory", (char*)fn);
                while (fchdir(fdwdir) == -1)
                        pause1cannot("change to initial working directory");
                return 0;
@@ -644,7 +652,7 @@ static unsigned logdir_open(struct logdir *ld, const char *fn)
        } else {
                if (errno != ENOENT) {
                        logdir_close(ld);
-                       warn2("cannot stat current", ld->name);
+                       warn2("can't stat current", ld->name);
                        while (fchdir(fdwdir) == -1)
                                pause1cannot("change to initial working directory");
                        return 0;
@@ -741,13 +749,13 @@ static int buffer_pread(/*int fd, */char *s, unsigned len)
                poll(&input, 1, i * 1000);
                sigprocmask(SIG_BLOCK, &blocked_sigset, NULL);
 
-               i = ndelay_read(0, s, len);
+               i = ndelay_read(STDIN_FILENO, s, len);
                if (i >= 0)
                        break;
                if (errno == EINTR)
                        continue;
                if (errno != EAGAIN) {
-                       warn("cannot read standard input");
+                       warn("can't read standard input");
                        break;
                }
                /* else: EAGAIN - normal, repeat silently */
@@ -781,20 +789,21 @@ static int buffer_pread(/*int fd, */char *s, unsigned len)
        return i;
 }
 
-static void sig_term_handler(int sig_no)
+static void sig_term_handler(int sig_no UNUSED_PARAM)
 {
        if (verbose)
                bb_error_msg(INFO"sig%s received", "term");
        exitasap = 1;
 }
 
-static void sig_child_handler(int sig_no)
+static void sig_child_handler(int sig_no UNUSED_PARAM)
 {
-       int pid, l;
+       pid_t pid;
+       int l;
 
        if (verbose)
                bb_error_msg(INFO"sig%s received", "child");
-       while ((pid = wait_nohang(&wstat)) > 0) {
+       while ((pid = wait_any_nohang(&wstat)) > 0) {
                for (l = 0; l < dirn; ++l) {
                        if (dir[l].ppid == pid) {
                                dir[l].ppid = 0;
@@ -805,14 +814,14 @@ static void sig_child_handler(int sig_no)
        }
 }
 
-static void sig_alarm_handler(int sig_no)
+static void sig_alarm_handler(int sig_no UNUSED_PARAM)
 {
        if (verbose)
                bb_error_msg(INFO"sig%s received", "alarm");
        rotateasap = 1;
 }
 
-static void sig_hangup_handler(int sig_no)
+static void sig_hangup_handler(int sig_no UNUSED_PARAM)
 {
        if (verbose)
                bb_error_msg(INFO"sig%s received", "hangup");
@@ -843,7 +852,7 @@ static void logmatch(struct logdir *ld)
        }
 }
 
-int svlogd_main(int argc, char **argv);
+int svlogd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int svlogd_main(int argc, char **argv)
 {
        char *r,*l,*b;
@@ -903,10 +912,10 @@ int svlogd_main(int argc, char **argv)
        sigaddset(&blocked_sigset, SIGALRM);
        sigaddset(&blocked_sigset, SIGHUP);
        sigprocmask(SIG_BLOCK, &blocked_sigset, NULL);
-       sig_catch(SIGTERM, sig_term_handler);
-       sig_catch(SIGCHLD, sig_child_handler);
-       sig_catch(SIGALRM, sig_alarm_handler);
-       sig_catch(SIGHUP, sig_hangup_handler);
+       bb_signals_recursive_norestart(1 << SIGTERM, sig_term_handler);
+       bb_signals_recursive_norestart(1 << SIGCHLD, sig_child_handler);
+       bb_signals_recursive_norestart(1 << SIGALRM, sig_alarm_handler);
+       bb_signals_recursive_norestart(1 << SIGHUP, sig_hangup_handler);
 
        logdirs_reopen();
 
@@ -985,9 +994,11 @@ int svlogd_main(int argc, char **argv)
                        if (ld->fddir == -1) continue;
                        if (ld->inst)
                                logmatch(ld);
-                       if (ld->matcherr == 'e')
-                               ////full_write(2, printptr, printlen);
-                               fwrite(lineptr, 1, linelen, stderr);
+                       if (ld->matcherr == 'e') {
+                               /* runit-1.8.0 compat: if timestamping, do it on stderr too */
+                               ////full_write(STDERR_FILENO, printptr, printlen);
+                               fwrite(printptr, 1, printlen, stderr);
+                       }
                        if (ld->match != '+') continue;
                        buffer_pwrite(i, printptr, printlen);
                }
@@ -1012,9 +1023,10 @@ int svlogd_main(int argc, char **argv)
                        /* linelen == no of chars incl. '\n' (or == stdin_cnt) */
                        for (i = 0; i < dirn; ++i) {
                                if (dir[i].fddir == -1) continue;
-                               if (dir[i].matcherr == 'e')
-                                       ////full_write(2, lineptr, linelen);
+                               if (dir[i].matcherr == 'e') {
+                                       ////full_write(STDERR_FILENO, lineptr, linelen);
                                        fwrite(lineptr, 1, linelen, stderr);
+                               }
                                if (dir[i].match != '+') continue;
                                buffer_pwrite(i, lineptr, linelen);
                        }