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