diff options
Diffstat (limited to 'src/lib9/rfork.c')
-rw-r--r-- | src/lib9/rfork.c | 153 |
1 files changed, 0 insertions, 153 deletions
diff --git a/src/lib9/rfork.c b/src/lib9/rfork.c deleted file mode 100644 index c9d632189..000000000 --- a/src/lib9/rfork.c +++ /dev/null @@ -1,153 +0,0 @@ -/* -Plan 9 from User Space src/lib9/rfork.c -http://code.swtch.com/plan9port/src/tip/src/lib9/rfork.c - -Copyright 2001-2007 Russ Cox. All Rights Reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ - -#include <u.h> -#include <sys/wait.h> -#include <signal.h> -#include <libc.h> -#undef rfork - -static void -nop(int x) -{ - USED(x); -} - -int -p9rfork(int flags) -{ - int pid, status; - int p[2]; - int n; - char buf[128], *q; - extern char **environ; - - if((flags&(RFPROC|RFFDG|RFMEM)) == (RFPROC|RFFDG)){ - /* check other flags before we commit */ - flags &= ~(RFPROC|RFFDG|RFENVG); - n = (flags & ~(RFNOTEG|RFNAMEG|RFNOWAIT|RFCENVG)); - if(n){ - werrstr("unknown flags %08ux in rfork", n); - return -1; - } - if(flags&RFNOWAIT){ - /* - * BUG - should put the signal handler back after we - * finish, but I just don't care. If a program calls with - * NOWAIT once, they're not likely to want child notes - * after that. - */ - signal(SIGCHLD, nop); - if(pipe(p) < 0) - return -1; - } - pid = fork(); - if(pid == -1) - return -1; - if(flags&RFNOWAIT){ - flags &= ~RFNOWAIT; - if(pid){ - /* - * Parent - wait for child to fork wait-free child. - * Then read pid from pipe. Assume pipe buffer can absorb the write. - */ - close(p[1]); - status = 0; - if(wait4(pid, &status, 0, 0) < 0){ - werrstr("pipe dance - wait4 - %r"); - close(p[0]); - return -1; - } - n = readn(p[0], buf, sizeof buf-1); - close(p[0]); - if(!WIFEXITED(status) || WEXITSTATUS(status)!=0 || n <= 0){ - if(!WIFEXITED(status)) - werrstr("pipe dance - !exited 0x%ux", status); - else if(WEXITSTATUS(status) != 0) - werrstr("pipe dance - non-zero status 0x%ux", status); - else if(n < 0) - werrstr("pipe dance - pipe read error - %r"); - else if(n == 0) - werrstr("pipe dance - pipe read eof"); - else - werrstr("pipe dance - unknown failure"); - return -1; - } - buf[n] = 0; - if(buf[0] == 'x'){ - werrstr("%s", buf+2); - return -1; - } - pid = strtol(buf, &q, 0); - }else{ - /* - * Child - fork a new child whose wait message can't - * get back to the parent because we're going to exit! - */ - signal(SIGCHLD, SIG_IGN); - close(p[0]); - pid = fork(); - if(pid){ - /* Child parent - send status over pipe and exit. */ - if(pid > 0) - fprint(p[1], "%d", pid); - else - fprint(p[1], "x %r"); - close(p[1]); - _exit(0); - }else{ - /* Child child - close pipe. */ - close(p[1]); - } - } - } - if(pid != 0) - return pid; - if(flags&RFCENVG) - if(environ) - *environ = nil; - } - if(flags&RFPROC){ - werrstr("cannot use rfork for shared memory -- use libthread"); - return -1; - } - if(flags&RFNAMEG){ - /* XXX set $NAMESPACE to a new directory */ - flags &= ~RFNAMEG; - } - if(flags&RFNOTEG){ - setpgid(0, getpid()); - flags &= ~RFNOTEG; - } - if(flags&RFNOWAIT){ - werrstr("cannot use RFNOWAIT without RFPROC"); - return -1; - } - if(flags){ - werrstr("unknown flags %08ux in rfork", flags); - return -1; - } - return 0; -} |