1 /* setsid.c - Run program in a new session ID.
2 *
3 * Copyright 2006 Rob Landley <[email protected]>
4
5 USE_SETSID(NEWTOY(setsid, "^<1wc@d[!dc]", TOYFLAG_USR|TOYFLAG_BIN))
6
7 config SETSID
8 bool "setsid"
9 default y
10 help
11 usage: setsid [-cdw] command [args...]
12
13 Run process in a new session.
14
15 -d Detach from tty
16 -c Control tty (repeat to steal)
17 -w Wait for child (and exit with its status)
18 */
19
20 #define FOR_setsid
21 #include "toys.h"
22
GLOBALS(long c;)23 GLOBALS(
24 long c;
25 )
26
27 void setsid_main(void)
28 {
29 int i;
30
31 // setsid() fails if we're already session leader, ala "exec setsid" from sh.
32 // Second call can't fail, so loop won't continue endlessly.
33 while (setsid()<0) {
34 pid_t pid;
35
36 // This must be before vfork() or tcsetpgrp() will hang waiting for parent.
37 setpgid(0, 0);
38
39 pid = XVFORK();
40 if (pid) {
41 i = 0;
42 if (FLAG(w)) {
43 i = 127;
44 if (pid>0) i = xwaitpid(pid);
45 }
46 _exit(i);
47 }
48 }
49
50 if (FLAG(c)) {
51 ioctl(0, TIOCSCTTY, TT.c>1);
52 tcsetpgrp(0, getpid());
53 } if (FLAG(d) && (i = open("/dev/tty", O_RDONLY)) != -1) {
54 ioctl(i, TIOCNOTTY);
55 close(i);
56 }
57 xexec(toys.optargs);
58 }
59