Introduction
Introduction Statistics Contact Development Disclaimer Help
rfork.c - 9base - revived minimalist port of Plan 9 userland to Unix
git clone git://git.suckless.org/9base
Log
Files
Refs
README
LICENSE
---
rfork.c (2824B)
---
1 #include <u.h>
2 #include <sys/wait.h>
3 #include <signal.h>
4 #include <libc.h>
5 #undef rfork
6
7 static void
8 nop(int x)
9 {
10 USED(x);
11 }
12
13 int
14 p9rfork(int flags)
15 {
16 int pid, status;
17 int p[2];
18 int n;
19 char buf[128], *q;
20 extern char **environ;
21
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));
26 if(n){
27 werrstr("unknown flags %08ux in rfork", n);
28 return -1;
29 }
30 if(flags&RFNOWAIT){
31 /*
32 * BUG - should put the signal handler back afte…
33 * finish, but I just don't care. If a program …
34 * NOWAIT once, they're not likely to want child…
35 * after that.
36 */
37 signal(SIGCHLD, nop);
38 if(pipe(p) < 0)
39 return -1;
40 }
41 pid = fork();
42 if(pid == -1)
43 return -1;
44 if(flags&RFNOWAIT){
45 flags &= ~RFNOWAIT;
46 if(pid){
47 /*
48 * Parent - wait for child to fork wait-…
49 * Then read pid from pipe. Assume pipe…
50 */
51 close(p[1]);
52 status = 0;
53 if(wait4(pid, &status, 0, 0) < 0){
54 werrstr("pipe dance - wait4 - %r…
55 close(p[0]);
56 return -1;
57 }
58 n = readn(p[0], buf, sizeof buf-1);
59 close(p[0]);
60 if(!WIFEXITED(status) || WEXITSTATUS(sta…
61 if(!WIFEXITED(status))
62 werrstr("pipe dance - !e…
63 else if(WEXITSTATUS(status) != 0)
64 werrstr("pipe dance - no…
65 else if(n < 0)
66 werrstr("pipe dance - pi…
67 else if(n == 0)
68 werrstr("pipe dance - pi…
69 else
70 werrstr("pipe dance - un…
71 return -1;
72 }
73 buf[n] = 0;
74 if(buf[0] == 'x'){
75 werrstr("%s", buf+2);
76 return -1;
77 }
78 pid = strtol(buf, &q, 0);
79 }else{
80 /*
81 * Child - fork a new child whose wait m…
82 * get back to the parent because we're …
83 */
84 signal(SIGCHLD, SIG_IGN);
85 close(p[0]);
86 pid = fork();
87 if(pid){
88 /* Child parent - send status ov…
89 if(pid > 0)
90 fprint(p[1], "%d", pid);
91 else
92 fprint(p[1], "x %r");
93 close(p[1]);
94 _exit(0);
95 }else{
96 /* Child child - close pipe. */
97 close(p[1]);
98 }
99 }
100 }
101 if(pid != 0)
102 return pid;
103 if(flags&RFCENVG)
104 if(environ)
105 *environ = nil;
106 }
107 if(flags&RFPROC){
108 werrstr("cannot use rfork for shared memory -- use libth…
109 return -1;
110 }
111 if(flags&RFNAMEG){
112 /* XXX set $NAMESPACE to a new directory */
113 flags &= ~RFNAMEG;
114 }
115 if(flags&RFNOTEG){
116 setpgid(0, getpid());
117 flags &= ~RFNOTEG;
118 }
119 if(flags&RFNOWAIT){
120 werrstr("cannot use RFNOWAIT without RFPROC");
121 return -1;
122 }
123 if(flags){
124 werrstr("unknown flags %08ux in rfork", flags);
125 return -1;
126 }
127 return 0;
128 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.