20 extern char **environ;
21 struct sigaction oldchld;
23 memset(&oldchld, 0, sizeof oldchld);
25 if((flags&(RFPROC|RFFDG|RFMEM)) == (RFPROC|RFFDG)){
26 /* check other flags before we commit */
27 flags &= ~(RFPROC|RFFDG|RFENVG);
28 n = (flags & ~(RFNOTEG|RFNAMEG|RFNOWAIT|RFCENVG));
30 werrstr("unknown flags %08ux in rfork", n);
34 sigaction(SIGCHLD, nil, &oldchld);
46 * Parent - wait for child to fork wait-free child.
47 * Then read pid from pipe. Assume pipe buffer can absorb the write.
51 if(wait4(pid, &status, 0, 0) < 0){
52 werrstr("pipe dance - wait4 - %r");
56 n = readn(p[0], buf, sizeof buf-1);
58 if(!WIFEXITED(status) || WEXITSTATUS(status)!=0 || n <= 0){
59 if(!WIFEXITED(status))
60 werrstr("pipe dance - !exited 0x%ux", status);
61 else if(WEXITSTATUS(status) != 0)
62 werrstr("pipe dance - non-zero status 0x%ux", status);
64 werrstr("pipe dance - pipe read error - %r");
66 werrstr("pipe dance - pipe read eof");
68 werrstr("pipe dance - unknown failure");
76 pid = strtol(buf, &q, 0);
79 * Child - fork a new child whose wait message can't
80 * get back to the parent because we're going to exit!
82 signal(SIGCHLD, SIG_IGN);
86 /* Child parent - send status over pipe and exit. */
88 fprint(p[1], "%d", pid);
94 /* Child child - close pipe. */
98 sigaction(SIGCHLD, &oldchld, nil);
107 werrstr("cannot use rfork for shared memory -- use libthread");
111 /* XXX set $NAMESPACE to a new directory */
115 setpgid(0, getpid());
119 werrstr("cannot use RFNOWAIT without RFPROC");
123 werrstr("unknown flags %08ux in rfork", flags);