diff options
Diffstat (limited to 'src/daemontools-extras/s6-setsid.c')
| -rw-r--r-- | src/daemontools-extras/s6-setsid.c | 106 |
1 files changed, 67 insertions, 39 deletions
diff --git a/src/daemontools-extras/s6-setsid.c b/src/daemontools-extras/s6-setsid.c index 6fd42dd..21662d0 100644 --- a/src/daemontools-extras/s6-setsid.c +++ b/src/daemontools-extras/s6-setsid.c @@ -1,69 +1,97 @@ /* ISC license. */ +#include <stdint.h> #include <unistd.h> #include <signal.h> +#include <skalibs/uint64.h> #include <skalibs/types.h> -#include <skalibs/sgetopt.h> -#include <skalibs/strerr.h> +#include <skalibs/envexec.h> #include <skalibs/sig.h> -#include <skalibs/exec.h> +#include <skalibs/djbunix.h> #define USAGE "s6-setsid [ -s | -b | -f | -g ] [ -i | -I | -q ] [ -d ctty ] prog..." #define dieusage() strerr_dieusage(100, USAGE) +enum golb_e +{ + GOLB_PGRP = 0x01, + GOLB_FG = 0x02, + GOLB_GRAB = 0x04, + GOLB_STRICT = 0x08, + GOLB_SILENT = 0x10, +} ; + +enum gola_e +{ + GOLA_CTTY, + GOLA_N +} ; + int main (int argc, char const *const *argv) { - unsigned int ctty = 0, what = 0, insist = 1 ; + static gol_bool const rgolb[] = + { + { .so = 's', .lo = "session", .clear = GOLB_PGRP | GOLB_FG | GOLB_GRAB, .set = 0 }, + { .so = 0, .lo = "process-group", .clear = 0, .set = GOLB_PGRP }, + { .so = 'b', .lo = "background-process-group", .clear = GOLB_FG | GOLB_GRAB, .set = GOLB_PGRP }, + { .so = 0, .lo = "foreground", .clear = 0, .set = GOLB_FG }, + { .so = 'f', .lo = "foreground-process-group", .clear = GOLB_GRAB, .set = GOLB_PGRP | GOLB_FG }, + { .so = 0, .lo = "grab", .clear = 0, .set = GOLB_GRAB }, + { .so = 'g', .lo = "foreground-process-group-grab", .clear = 0, .set = GOLB_PGRP | GOLB_FG | GOLB_GRAB }, + { .so = 'I', .lo = "no-strict", .clear = GOLB_STRICT, .set = 0 }, + { .so = 'i', .lo = "strict", .clear = 0, .set = GOLB_STRICT }, + { .so = 'q', .lo = "quiet", .clear = 0, .set = GOLB_SILENT } + } ; + static gol_arg const rgola[] = + { + { .so = 'd', .lo = "ctty", .i = GOLA_CTTY }, + } ; + char const *wgola[GOLA_N] = { 0 } ; + uint64_t wgolb = 0 ; + unsigned int ctty = 0 ; + unsigned int golc ; PROG = "s6-setsid" ; + + golc = GOL_main(argc, argv, rgolb, rgola, &wgolb, wgola) ; + argc -= golc ; argv += golc ; + if (!argc) dieusage() ; + if (wgola[GOLA_CTTY]) { - subgetopt l = SUBGETOPT_ZERO ; - for (;;) - { - int opt = subgetopt_r(argc, argv, "sbfgiIqd:", &l) ; - if (opt == -1) break ; - switch (opt) - { - case 's' : what = 0 ; break ; - case 'b' : what = 1 ; break ; - case 'f' : what = 2 ; break ; - case 'g' : what = 3 ; break ; - case 'i' : insist = 2 ; break ; - case 'I' : insist = 1 ; break ; - case 'q' : insist = 0 ; break ; - case 'd' : if (!uint0_scan(l.arg, &ctty)) dieusage() ; break ; - default : dieusage() ; - } - } - argc -= l.ind ; argv += l.ind ; + if (!uint0_scan(wgola[GOLA_CTTY], &ctty)) dieusage() ; + } + else if (wgolb & (GOLB_PGRP | GOLB_FG)) + { + int fd = openc_read("/dev/tty") ; + if (fd == -1) strerr_diefu2sys(111, "open ", "/dev/tty") ; + ctty = fd ; } - if (!argc) dieusage() ; - if (what) + if (wgolb & GOLB_PGRP) { - if (setpgid(0, 0) < 0) switch (insist) + if (setpgid(0, 0) == -1) { - case 2 : strerr_diefu1sys(111, "setpgid") ; - case 1 : strerr_warnwu1sys("setpgid") ; break ; - default : break ; + if (wgolb & GOLB_STRICT) strerr_diefu1sys(111, "setpgid") ; + if (!(wgolb & GOLB_SILENT)) strerr_warnwu1sys("setpgid") ; } - if (what >= 2) + if (wgolb & GOLB_FG) { - if (what == 3) sig_altignore(SIGTTOU) ; - if (tcsetpgrp(ctty, getpid()) < 0) switch (insist) + if (wgolb & GOLB_GRAB) sig_altignore(SIGTTOU) ; + if (tcsetpgrp(ctty, getpid()) == -1) { - case 2 : strerr_diefu1sys(111, "tcsetpgrp") ; - case 1 : strerr_warnwu1sys("tcsetpgrp") ; break ; - default : break ; + if (wgolb & GOLB_STRICT) strerr_diefu1sys(111, "tcsetpgrp") ; + if (!(wgolb & GOLB_SILENT)) strerr_warnwu1sys("tcsetpgrp") ; } } } - else if (setsid() < 0) switch (insist) + else { - case 2 : strerr_diefu1sys(111, "setsid") ; - case 1 : strerr_warnwu1sys("setsid") ; break ; - default : break ; + if (setsid() == -1) + { + if (wgolb & GOLB_STRICT) strerr_diefu1sys(111, "setsid") ; + if (!(wgolb & GOLB_SILENT)) strerr_warnwu1sys("setsid") ; + } } xexec(argv) ; |
