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