int main (int argc, char const *const *argv, char const *const *envp) { iopause_fd x[2] = { { -1, IOPAUSE_READ, 0 }, { -1, IOPAUSE_READ, 0 } } ; struct taia deadline, tto ; ftrigr_t a = FTRIGR_ZERO ; int pid ; uint16 id ; PROG = "s6-ftrig-listen1" ; { unsigned int t = 0 ; for (;;) { register int opt = subgetopt(argc, argv, "t:") ; if (opt == -1) break ; switch (opt) { case 't' : if (uint0_scan(subgetopt_here.arg, &t)) break ; default : strerr_dieusage(100, USAGE) ; } } if (t) taia_from_millisecs(&tto, t) ; else tto = infinitetto ; argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ; } if (argc < 3) strerr_dieusage(100, USAGE) ; taia_now_g() ; taia_add_g(&deadline, &tto) ; if (!ftrigr_startf_g(&a, &deadline)) strerr_diefu1sys(111, "ftrigr_startf") ; id = ftrigr_subscribe_g(&a, argv[0], argv[1], 0, &deadline) ; if (!id) strerr_diefu4sys(111, "subscribe to ", argv[0], " with regexp ", argv[1]) ; x[0].fd = selfpipe_init() ; if (x[0].fd < 0) strerr_diefu1sys(111, "selfpipe_init") ; if (selfpipe_trap(SIGCHLD) < 0) strerr_diefu1sys(111, "selfpipe_trap") ; if (sig_ignore(SIGPIPE) < 0) strerr_diefu1sys(111, "sig_ignore") ; x[1].fd = ftrigr_fd(&a) ; pid = fork() ; switch (pid) { case -1 : strerr_diefu1sys(111, "fork") ; case 0 : { PROG = "s6-ftrig-listen1 (child)" ; pathexec_run(argv[2], argv+2, envp) ; strerr_dieexec(111, argv[2]) ; } } for (;;) { char dummy ; register int r = ftrigr_check(&a, id, &dummy) ; if (r < 0) strerr_diefu1sys(111, "ftrigr_check") ; if (r) break ; r = iopause_g(x, 2, &deadline) ; if (r < 0) strerr_diefu1sys(111, "iopause") ; else if (!r) { errno = ETIMEDOUT ; strerr_diefu1sys(1, "get expected event") ; } if (x[0].revents & IOPAUSE_READ) handle_signals() ; if (x[1].revents & IOPAUSE_READ) { if (ftrigr_update(&a) < 0) strerr_diefu1sys(111, "ftrigr_update") ; } } return 0 ; }
int main (int argc, char const **argv, char const *const *envp) { iopause_fd x[2] = { { -1, IOPAUSE_READ, 0 }, { -1, IOPAUSE_READ, 0 } } ; tain_t deadline, tto ; ftrigr_t a = FTRIGR_ZERO ; int argc1 ; unsigned int i = 0 ; char or = 0 ; PROG = "s6-ftrig-listen" ; { unsigned int t = 0 ; for (;;) { register int opt = subgetopt(argc, argv, "aot:") ; if (opt == -1) break ; switch (opt) { case 'a' : or = 0 ; break ; case 'o' : or = 1 ; break ; case 't' : if (uint0_scan(subgetopt_here.arg, &t)) break ; default : dieusage() ; } } if (t) tain_from_millisecs(&tto, t) ; else tto = tain_infinite_relative ; argc -= subgetopt_here.ind ; argv += subgetopt_here.ind ; } if (argc < 4) dieusage() ; argc1 = el_semicolon(argv) ; if (!argc1 || (argc1 & 1) || (argc == argc1 + 1)) dieusage() ; if (argc1 >= argc) strerr_dief1x(100, "unterminated fifodir+regex block") ; tain_now_g() ; tain_add_g(&deadline, &tto) ; x[0].fd = selfpipe_init() ; if (x[0].fd < 0) strerr_diefu1sys(111, "selfpipe_init") ; if (selfpipe_trap(SIGCHLD) < 0) strerr_diefu1sys(111, "selfpipe_trap") ; if (sig_ignore(SIGPIPE) < 0) strerr_diefu1sys(111, "sig_ignore") ; if (!ftrigr_startf_g(&a, &deadline)) strerr_diefu1sys(111, "ftrigr_startf") ; x[1].fd = ftrigr_fd(&a) ; { int pid = 0 ; unsigned int idlen = argc1 >> 1 ; uint16 ids[idlen] ; for (; i < idlen ; i++) { ids[i] = ftrigr_subscribe_g(&a, argv[i<<1], argv[(i<<1)+1], 0, &deadline) ; if (!ids[i]) strerr_diefu4sys(111, "subscribe to ", argv[i<<1], " with regexp ", argv[(i<<1)+1]) ; } pid = child_spawn0(argv[argc1 + 1], argv + argc1 + 1, envp) ; if (!pid) strerr_diefu2sys(111, "spawn ", argv[argc1 + 1]) ; for (;;) { register int r ; i = 0 ; while (i < idlen) { char dummy ; r = ftrigr_check(&a, ids[i], &dummy) ; if (r < 0) strerr_diefu1sys(111, "ftrigr_check") ; else if (!r) i++ ; else if (or) idlen = 0 ; else ids[i] = ids[--idlen] ; } if (!idlen) break ; r = iopause_g(x, 2, &deadline) ; if (r < 0) strerr_diefu1sys(111, "iopause") ; else if (!r) { errno = ETIMEDOUT ; strerr_diefu1sys(1, "get expected event") ; } if (x[0].revents & IOPAUSE_READ) handle_signals() ; if (x[1].revents & IOPAUSE_READ) { if (ftrigr_update(&a) < 0) strerr_diefu1sys(111, "ftrigr_update") ; } } } return 0 ; }
} } static inline int got (s6_svlisten_t const *foo, int wantup, int wantready, int or) { register unsigned int m = bitarray_div8(foo->n) ; unsigned char t[m] ; byte_copy(t, m, foo->upstate) ; if (!wantup) bitarray_not(t, 0, foo->n) ; if (wantready) bitarray_and(t, t, foo->readystate, foo->n) ; return (bitarray_first(t, foo->n, or) < foo->n) == or ; } int s6_svlisten_loop (s6_svlisten_t *foo, int wantup, int wantready, int or, tain_t const *deadline, int spfd, action_func_t_ref handler) { iopause_fd x[2] = { { .fd = ftrigr_fd(&foo->a), .events = IOPAUSE_READ }, { .fd = spfd, .events = IOPAUSE_READ, .revents = 0 } } ; while (!got(foo, wantup, wantready, or)) { register int r = iopause_g(x, 1 + (spfd >= 0), deadline) ; if (r < 0) strerr_diefu1sys(111, "iopause") ; else if (!r) strerr_dief1x(1, "timed out") ; if (x[1].revents & IOPAUSE_READ) (*handler)() ; if (x[0].revents & IOPAUSE_READ) { register unsigned int i = 0 ; if (ftrigr_update(&foo->a) < 0) strerr_diefu1sys(111, "ftrigr_update") ; for (; i < foo->n ; i++) { char what ; register int r = ftrigr_check(&foo->a, foo->ids[i], &what) ; if (r < 0) strerr_diefu1sys(111, "ftrigr_check") ;