From 4817036313bde019e4639bf52e7a6c52ca715c61 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Thu, 26 Dec 2019 16:45:58 -0600 Subject: Fix setsid with vfork, redo command line arguments. Switch -t to -c (like man page says), add -w (wait) and -d (detach from tty) --- toys/other/setsid.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) (limited to 'toys/other/setsid.c') diff --git a/toys/other/setsid.c b/toys/other/setsid.c index 95698260..57a926ef 100644 --- a/toys/other/setsid.c +++ b/toys/other/setsid.c @@ -2,27 +2,49 @@ * * Copyright 2006 Rob Landley -USE_SETSID(NEWTOY(setsid, "^<1t", TOYFLAG_USR|TOYFLAG_BIN)) +USE_SETSID(NEWTOY(setsid, "^<1wcd[!dc]", TOYFLAG_USR|TOYFLAG_BIN)) config SETSID bool "setsid" default y help - usage: setsid [-t] command [args...] + usage: setsid [-cdw] command [args...] Run process in a new session. - -t Grab tty (become foreground process, receiving keyboard signals) + -d Detach from tty + -c Control tty (become foreground process & receive keyboard signals) */ +#define FOR_setsid #include "toys.h" void setsid_main(void) { - while (setsid()<0) if (XVFORK()) _exit(0); - if (toys.optflags) { - setpgid(0, 0); - tcsetpgrp(0, getpid()); + int i; + + // This must be before vfork() or tcsetpgrp() will hang waiting for parent. + setpgid(0, 0); + + // setsid() fails if we're already session leader, ala "exec setsid" from sh. + // Second call can't fail, so loop won't continue endlessly. + while (setsid()<0) { + pid_t pid = XVFORK(); + + if (pid) { + i = 0; + if (FLAG(w)) { + i = 127; + if (pid>0) i = xwaitpid(pid); + } + _exit(i); + } + } + + if (FLAG(c)) tcsetpgrp(0, getpid()); + if (FLAG(d) && (i = open("/dev/tty", O_RDONLY)) != -1) { + ioctl(i, TIOCNOTTY); + close(i); } xexec(toys.optargs); } -- cgit v1.2.3