20 extern char **environ;
22 if((flags&(RFPROC|RFFDG|RFMEM)) == (RFPROC|RFFDG)){
23 /* check other flags before we commit */
24 flags &= ~(RFPROC|RFFDG|RFENVG);
25 n = (flags & ~(RFNOTEG|RFNAMEG|RFNOWAIT|RFCENVG));
27 werrstr("unknown flags %08ux in rfork", n);
32 * BUG - should put the signal handler back after we
33 * finish, but I just don't care. If a program calls with
34 * NOWAIT once, they're not likely to want child notes
48 * Parent - wait for child to fork wait-free child.
49 * Then read pid from pipe. Assume pipe buffer can absorb the write.
53 if(wait4(pid, &status, 0, 0) < 0){
54 werrstr("pipe dance - wait4 - %r");
58 n = readn(p[0], buf, sizeof buf-1);
60 if(!WIFEXITED(status) || WEXITSTATUS(status)!=0 || n <= 0){
61 if(!WIFEXITED(status))
62 werrstr("pipe dance - !exited 0x%ux", status);
63 else if(WEXITSTATUS(status) != 0)
64 werrstr("pipe dance - non-zero status 0x%ux", status);
66 werrstr("pipe dance - pipe read error - %r");
68 werrstr("pipe dance - pipe read eof");
70 werrstr("pipe dance - unknown failure");
78 pid = strtol(buf, &q, 0);
81 * Child - fork a new child whose wait message can't
82 * get back to the parent because we're going to exit!
84 signal(SIGCHLD, SIG_IGN);
88 /* Child parent - send status over pipe and exit. */
90 fprint(p[1], "%d", pid);
96 /* Child child - close pipe. */
108 werrstr("cannot use rfork for shared memory -- use libthread");
112 /* XXX set $NAMESPACE to a new directory */
116 setpgid(0, getpid());
120 werrstr("cannot use RFNOWAIT without RFPROC");
124 werrstr("unknown flags %08ux in rfork", flags);