int runsvdir_main(int argc, char **argv) { struct stat s; dev_t last_dev = last_dev; /* for gcc */ ino_t last_ino = last_ino; /* for gcc */ time_t last_mtime = 0; int wstat; int curdir; int pid; unsigned deadline; unsigned now; unsigned stampcheck; char ch; int i; argv++; if (!*argv) bb_show_usage(); if (argv[0][0] == '-') { switch (argv[0][1]) { case 'P': set_pgrp = 1; case '-': ++argv; } if (!*argv) bb_show_usage(); } sig_catch(SIGTERM, s_term); sig_catch(SIGHUP, s_hangup); svdir = *argv++; if (argv && *argv) { rplog = *argv; if (setup_log() != 1) { rplog = 0; warnx("log service disabled"); } } curdir = open_read("."); if (curdir == -1) fatal2_cannot("open current directory", ""); coe(curdir); stampcheck = monotonic_sec(); for (;;) { /* collect children */ for (;;) { pid = wait_nohang(&wstat); if (pid <= 0) break; for (i = 0; i < svnum; i++) { if (pid == sv[i].pid) { /* runsv has gone */ sv[i].pid = 0; check = 1; break; } } } now = monotonic_sec(); if ((int)(now - stampcheck) >= 0) { /* wait at least a second */ stampcheck = now + 1; if (stat(svdir, &s) != -1) { if (check || s.st_mtime != last_mtime || s.st_ino != last_ino || s.st_dev != last_dev ) { /* svdir modified */ if (chdir(svdir) != -1) { last_mtime = s.st_mtime; last_dev = s.st_dev; last_ino = s.st_ino; check = 0; //if (now <= mtime) // sleep(1); runsvdir(); while (fchdir(curdir) == -1) { warn2_cannot("change directory, pausing", ""); sleep(5); } } else warn2_cannot("change directory to ", svdir); } } else warn2_cannot("stat ", svdir); } if (rplog) { if ((int)(now - stamplog) >= 0) { write(logpipe[1], ".", 1); stamplog = now + 900; } } pfd[0].revents = 0; sig_block(SIGCHLD); deadline = (check ? 1 : 5); if (rplog) poll(pfd, 1, deadline*1000); else sleep(deadline); sig_unblock(SIGCHLD); if (pfd[0].revents & POLLIN) { while (read(logpipe[0], &ch, 1) > 0) { if (ch) { for (i = 6; i < rploglen; i++) rplog[i-1] = rplog[i]; rplog[rploglen-1] = ch; } } } switch (exitsoon) { case 1: _exit(0); case 2: for (i = 0; i < svnum; i++) if (sv[i].pid) kill(sv[i].pid, SIGTERM); _exit(111); } } /* not reached */ return 0; }
int main(int argc, char **argv) { struct stat s; time_t mtime =0; int wstat; int curdir; int pid; struct taia deadline; struct taia now; struct taia stampcheck; char ch; int i; progname =*argv++; if (! argv || ! *argv) usage(); if (**argv == '-') { switch (*(*argv +1)) { case 'P': pgrp =1; case '-': ++argv; } if (! argv || ! *argv) usage(); } sig_catch(sig_term, s_term); sig_catch(sig_hangup, s_hangup); svdir =*argv++; if (argv && *argv) { rplog =*argv; if (setup_log() != 1) { rplog =0; warn3x("log service disabled.", 0, 0); } } if ((curdir =open_read(".")) == -1) fatal("unable to open current directory", 0); coe(curdir); taia_now(&stampcheck); for (;;) { /* collect children */ for (;;) { if ((pid =wait_nohang(&wstat)) <= 0) break; for (i =0; i < svnum; i++) { if (pid == sv[i].pid) { /* runsv has gone */ sv[i].pid =0; check =1; break; } } } taia_now(&now); if (now.sec.x < (stampcheck.sec.x -3)) { /* time warp */ warn3x("time warp: resetting time stamp.", 0, 0); taia_now(&stampcheck); taia_now(&now); if (rplog) taia_now(&stamplog); } if (taia_less(&now, &stampcheck) == 0) { /* wait at least a second */ taia_uint(&deadline, 1); taia_add(&stampcheck, &now, &deadline); if (stat(svdir, &s) != -1) { if (check || \ s.st_mtime != mtime || s.st_ino != ino || s.st_dev != dev) { /* svdir modified */ if (chdir(svdir) != -1) { mtime =s.st_mtime; dev =s.st_dev; ino =s.st_ino; check =0; if (now.sec.x <= (4611686018427387914ULL +(uint64)mtime)) sleep(1); runsvdir(); while (fchdir(curdir) == -1) { warn("unable to change directory, pausing", 0); sleep(5); } } else warn("unable to change directory to ", svdir); } } else warn("unable to stat ", svdir); } if (rplog) if (taia_less(&now, &stamplog) == 0) { write(logpipe[1], ".", 1); taia_uint(&deadline, 900); taia_add(&stamplog, &now, &deadline); } /* half a second */ deadline.sec.x =0; deadline.nano =500000000UL; deadline.atto =0; taia_add(&deadline, &now, &deadline); sig_block(sig_child); if (rplog) iopause(io, 1, &deadline, &now); else iopause(0, 0, &deadline, &now); sig_unblock(sig_child); if (rplog && (io[0].revents | IOPAUSE_READ)) while (read(logpipe[0], &ch, 1) > 0) if (ch) { for (i =6; i < rploglen; i++) rplog[i -1] =rplog[i]; rplog[rploglen -1] =ch; } switch(exitsoon) { case 1: _exit(0); case 2: for (i =0; i < svnum; i++) if (sv[i].pid) kill(sv[i].pid, SIGTERM); _exit(111); } } /* for (;;) */ /* not reached */ _exit(0); }