havefork.c - 9base - revived minimalist port of Plan 9 userland to Unix | |
git clone git://git.suckless.org/9base | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
havefork.c (4415B) | |
--- | |
1 #include <u.h> | |
2 #include <signal.h> | |
3 #include "rc.h" | |
4 #include "getflags.h" | |
5 #include "exec.h" | |
6 #include "io.h" | |
7 #include "fns.h" | |
8 | |
9 int havefork = 1; | |
10 | |
11 void | |
12 Xasync(void) | |
13 { | |
14 int null = open("/dev/null", 0); | |
15 int pid; | |
16 char npid[10]; | |
17 if(null<0){ | |
18 Xerror("Can't open /dev/null\n"); | |
19 return; | |
20 } | |
21 switch(pid = rfork(RFFDG|RFPROC|RFNOTEG)){ | |
22 case -1: | |
23 close(null); | |
24 Xerror("try again"); | |
25 break; | |
26 case 0: | |
27 clearwaitpids(); | |
28 pushredir(ROPEN, null, 0); | |
29 start(runq->code, runq->pc+1, runq->local); | |
30 runq->ret = 0; | |
31 break; | |
32 default: | |
33 addwaitpid(pid); | |
34 close(null); | |
35 runq->pc = runq->code[runq->pc].i; | |
36 inttoascii(npid, pid); | |
37 setvar("apid", newword(npid, (word *)0)); | |
38 break; | |
39 } | |
40 } | |
41 | |
42 void | |
43 Xpipe(void) | |
44 { | |
45 struct thread *p = runq; | |
46 int pc = p->pc, forkid; | |
47 int lfd = p->code[pc++].i; | |
48 int rfd = p->code[pc++].i; | |
49 int pfd[2]; | |
50 if(pipe(pfd)<0){ | |
51 Xerror("can't get pipe"); | |
52 return; | |
53 } | |
54 switch(forkid = fork()){ | |
55 case -1: | |
56 Xerror("try again"); | |
57 break; | |
58 case 0: | |
59 clearwaitpids(); | |
60 start(p->code, pc+2, runq->local); | |
61 runq->ret = 0; | |
62 close(pfd[PRD]); | |
63 pushredir(ROPEN, pfd[PWR], lfd); | |
64 break; | |
65 default: | |
66 addwaitpid(forkid); | |
67 start(p->code, p->code[pc].i, runq->local); | |
68 close(pfd[PWR]); | |
69 pushredir(ROPEN, pfd[PRD], rfd); | |
70 p->pc = p->code[pc+1].i; | |
71 p->pid = forkid; | |
72 break; | |
73 } | |
74 } | |
75 | |
76 /* | |
77 * Who should wait for the exit from the fork? | |
78 */ | |
79 void | |
80 Xbackq(void) | |
81 { | |
82 struct thread *p = runq; | |
83 char wd[8193]; | |
84 int c, n; | |
85 char *s, *ewd=&wd[8192], *stop, *q; | |
86 struct io *f; | |
87 var *ifs = vlook("ifs"); | |
88 word *v, *nextv; | |
89 int pfd[2]; | |
90 int pid; | |
91 Rune r; | |
92 stop = ifs->val?ifs->val->word:""; | |
93 if(pipe(pfd)<0){ | |
94 Xerror("can't make pipe"); | |
95 return; | |
96 } | |
97 switch(pid = fork()){ | |
98 case -1: | |
99 Xerror("try again"); | |
100 close(pfd[PRD]); | |
101 close(pfd[PWR]); | |
102 return; | |
103 case 0: | |
104 clearwaitpids(); | |
105 close(pfd[PRD]); | |
106 start(runq->code, runq->pc+1, runq->local); | |
107 pushredir(ROPEN, pfd[PWR], 1); | |
108 return; | |
109 default: | |
110 addwaitpid(pid); | |
111 close(pfd[PWR]); | |
112 f = openfd(pfd[PRD]); | |
113 s = wd; | |
114 v = 0; | |
115 while((c = rchr(f))!=EOF){ | |
116 if(s != ewd) { | |
117 *s++ = c; | |
118 for(q=stop; *q; q+=n) { | |
119 n = chartorune(&r, q); | |
120 if(s-wd >= n && memcmp(s-n, q, n… | |
121 s -= n; | |
122 goto stop; | |
123 } | |
124 } | |
125 continue; | |
126 } | |
127 stop: | |
128 if(s != wd) { | |
129 *s = '\0'; | |
130 v = newword(wd, v); | |
131 } | |
132 s = wd; | |
133 } | |
134 if(s!=wd){ | |
135 *s='\0'; | |
136 v = newword(wd, v); | |
137 } | |
138 closeio(f); | |
139 Waitfor(pid, 0); | |
140 /* v points to reversed arglist -- reverse it onto argv … | |
141 while(v){ | |
142 nextv = v->next; | |
143 v->next = runq->argv->words; | |
144 runq->argv->words = v; | |
145 v = nextv; | |
146 } | |
147 p->pc = p->code[p->pc].i; | |
148 return; | |
149 } | |
150 } | |
151 | |
152 void | |
153 Xpipefd(void) | |
154 { | |
155 struct thread *p = runq; | |
156 int pc = p->pc, pid; | |
157 char name[40]; | |
158 int pfd[2]; | |
159 struct { int sidefd, mainfd; } fd[2], *r, *w; | |
160 | |
161 r = &fd[0]; | |
162 w = &fd[1]; | |
163 switch(p->code[pc].i){ | |
164 case READ: | |
165 w = nil; | |
166 break; | |
167 case WRITE: | |
168 r = nil; | |
169 } | |
170 | |
171 if(r){ | |
172 if(pipe(pfd)<0){ | |
173 Xerror("can't get pipe"); | |
174 return; | |
175 } | |
176 r->sidefd = pfd[PWR]; | |
177 r->mainfd = pfd[PRD]; | |
178 } | |
179 if(w){ | |
180 if(pipe(pfd)<0){ | |
181 Xerror("can't get pipe"); | |
182 return; | |
183 } | |
184 w->sidefd = pfd[PRD]; | |
185 w->mainfd = pfd[PWR]; | |
186 } | |
187 switch(pid = fork()){ | |
188 case -1: | |
189 Xerror("try again"); | |
190 break; | |
191 case 0: | |
192 clearwaitpids(); | |
193 start(p->code, pc+2, runq->local); | |
194 if(r){ | |
195 close(r->mainfd); | |
196 pushredir(ROPEN, r->sidefd, 1); | |
197 } | |
198 if(w){ | |
199 close(w->mainfd); | |
200 pushredir(ROPEN, w->sidefd, 0); | |
201 } | |
202 runq->ret = 0; | |
203 break; | |
204 default: | |
205 addwaitpid(pid); | |
206 if(w){ | |
207 close(w->sidefd); | |
208 pushredir(ROPEN, w->mainfd, w->mainfd); /… | |
209 strcpy(name, Fdprefix); | |
210 inttoascii(name+strlen(name), w->mainfd); | |
211 pushword(name); | |
212 } | |
213 if(r){ | |
214 close(r->sidefd); | |
215 pushredir(ROPEN, r->mainfd, r->mainfd); | |
216 strcpy(name, Fdprefix); | |
217 inttoascii(name+strlen(name), r->mainfd); | |
218 pushword(name); | |
219 } | |
220 p->pc = p->code[pc+1].i; | |
221 break; | |
222 } | |
223 } | |
224 | |
225 void | |
226 Xsubshell(void) | |
227 { | |
228 int pid; | |
229 switch(pid = fork()){ | |
230 case -1: | |
231 Xerror("try again"); | |
232 break; | |
233 case 0: | |
234 clearwaitpids(); | |
235 start(runq->code, runq->pc+1, runq->local); | |
236 runq->ret = 0; | |
237 break; | |
238 default: | |
239 addwaitpid(pid); | |
240 Waitfor(pid, 1); | |
241 runq->pc = runq->code[runq->pc].i; | |
242 break; | |
243 } | |
244 } | |
245 | |
246 int | |
247 execforkexec(void) | |
248 { | |
249 int pid; | |
250 int n; | |
251 char buf[ERRMAX]; | |
252 | |
253 switch(pid = fork()){ | |
254 case -1: | |
255 return -1; | |
256 case 0: | |
257 clearwaitpids(); | |
258 pushword("exec"); | |
259 execexec(); | |
260 strcpy(buf, "can't exec: "); | |
261 n = strlen(buf); | |
262 errstr(buf+n, ERRMAX-n); | |
263 Exit(buf); | |
264 } | |
265 addwaitpid(pid); | |
266 return pid; | |
267 } |