Introduction
Introduction Statistics Contact Development Disclaimer Help
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 }
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.