1 /* setsid.c - Run program in a new session ID. 2 * 3 * Copyright 2006 Rob Landley <rob@landley.net> 4 5 USE_SETSID(NEWTOY(setsid, "^<1wcd[!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 (become foreground process & receive keyboard signals) 17 -w Wait for child (and exit with its status) 18 */ 19 20 #define FOR_setsid 21 #include "toys.h" 22 setsid_main(void)23void setsid_main(void) 24 { 25 int i; 26 27 // setsid() fails if we're already session leader, ala "exec setsid" from sh. 28 // Second call can't fail, so loop won't continue endlessly. 29 while (setsid()<0) { 30 pid_t pid; 31 32 // This must be before vfork() or tcsetpgrp() will hang waiting for parent. 33 setpgid(0, 0); 34 35 pid = XVFORK(); 36 if (pid) { 37 i = 0; 38 if (FLAG(w)) { 39 i = 127; 40 if (pid>0) i = xwaitpid(pid); 41 } 42 _exit(i); 43 } 44 } 45 46 if (FLAG(c)) tcsetpgrp(0, getpid()); 47 if (FLAG(d) && (i = open("/dev/tty", O_RDONLY)) != -1) { 48 ioctl(i, TIOCNOTTY); 49 close(i); 50 } 51 xexec(toys.optargs); 52 } 53