xref: /aosp_15_r20/external/toybox/toys/other/setsid.c (revision cf5a6c84e2b8763fc1a7db14496fd4742913b199)
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