Blob


1 #include "rc.h"
2 #include "getflags.h"
3 #include "exec.h"
4 #include "io.h"
5 #include "fns.h"
7 int havefork = 1;
9 void
10 Xasync(void)
11 {
12 int null = open("/dev/null", 0);
13 int pid;
14 char npid[10];
15 if(null<0){
16 Xerror("Can't open /dev/null\n");
17 return;
18 }
19 switch(pid = rfork(RFFDG|RFPROC|RFNOTEG)){
20 case -1:
21 close(null);
22 Xerror("try again");
23 break;
24 case 0:
25 pushredir(ROPEN, null, 0);
26 start(runq->code, runq->pc+1, runq->local);
27 runq->ret = 0;
28 break;
29 default:
30 close(null);
31 runq->pc = runq->code[runq->pc].i;
32 inttoascii(npid, pid);
33 setvar("apid", newword(npid, (word *)0));
34 break;
35 }
36 }
38 void
39 Xpipe(void)
40 {
41 struct thread *p = runq;
42 int pc = p->pc, forkid;
43 int lfd = p->code[pc++].i;
44 int rfd = p->code[pc++].i;
45 int pfd[2];
46 if(pipe(pfd)<0){
47 Xerror("can't get pipe");
48 return;
49 }
50 switch(forkid = fork()){
51 case -1:
52 Xerror("try again");
53 break;
54 case 0:
55 start(p->code, pc+2, runq->local);
56 runq->ret = 0;
57 close(pfd[PRD]);
58 pushredir(ROPEN, pfd[PWR], lfd);
59 break;
60 default:
61 start(p->code, p->code[pc].i, runq->local);
62 close(pfd[PWR]);
63 pushredir(ROPEN, pfd[PRD], rfd);
64 p->pc = p->code[pc+1].i;
65 p->pid = forkid;
66 break;
67 }
68 }
70 /*
71 * Who should wait for the exit from the fork?
72 */
73 void
74 Xbackq(void)
75 {
76 char wd[8193];
77 int c;
78 char *s, *ewd=&wd[8192], *stop;
79 struct io *f;
80 var *ifs = vlook("ifs");
81 word *v, *nextv;
82 int pfd[2];
83 int pid;
84 stop = ifs->val?ifs->val->word:"";
85 if(pipe(pfd)<0){
86 Xerror("can't make pipe");
87 return;
88 }
89 switch(pid = fork()){
90 case -1:
91 Xerror("try again");
92 close(pfd[PRD]);
93 close(pfd[PWR]);
94 return;
95 case 0:
96 close(pfd[PRD]);
97 start(runq->code, runq->pc+1, runq->local);
98 pushredir(ROPEN, pfd[PWR], 1);
99 return;
100 default:
101 close(pfd[PWR]);
102 f = openfd(pfd[PRD]);
103 s = wd;
104 v = 0;
105 while((c = rchr(f))!=EOF){
106 if(strchr(stop, c) || s==ewd){
107 if(s!=wd){
108 *s='\0';
109 v = newword(wd, v);
110 s = wd;
113 else *s++=c;
115 if(s!=wd){
116 *s='\0';
117 v = newword(wd, v);
119 closeio(f);
120 Waitfor(pid, 0);
121 /* v points to reversed arglist -- reverse it onto argv */
122 while(v){
123 nextv = v->next;
124 v->next = runq->argv->words;
125 runq->argv->words = v;
126 v = nextv;
128 runq->pc = runq->code[runq->pc].i;
129 return;
133 void
134 Xpipefd(void)
136 struct thread *p = runq;
137 int pc = p->pc;
138 char name[40];
139 int pfd[2];
140 int sidefd, mainfd;
141 if(pipe(pfd)<0){
142 Xerror("can't get pipe");
143 return;
145 if(p->code[pc].i==READ){
146 sidefd = pfd[PWR];
147 mainfd = pfd[PRD];
149 else{
150 sidefd = pfd[PRD];
151 mainfd = pfd[PWR];
153 switch(fork()){
154 case -1:
155 Xerror("try again");
156 break;
157 case 0:
158 start(p->code, pc+2, runq->local);
159 close(mainfd);
160 pushredir(ROPEN, sidefd, p->code[pc].i==READ?1:0);
161 runq->ret = 0;
162 break;
163 default:
164 close(sidefd);
165 pushredir(ROPEN, mainfd, mainfd); /* isn't this a noop? */
166 strcpy(name, Fdprefix);
167 inttoascii(name+strlen(name), mainfd);
168 pushword(name);
169 p->pc = p->code[pc+1].i;
170 break;
174 void
175 Xsubshell(void)
177 int pid;
178 switch(pid = fork()){
179 case -1:
180 Xerror("try again");
181 break;
182 case 0:
183 start(runq->code, runq->pc+1, runq->local);
184 runq->ret = 0;
185 break;
186 default:
187 Waitfor(pid, 1);
188 runq->pc = runq->code[runq->pc].i;
189 break;
193 int
194 execforkexec(void)
196 int pid;
197 int n;
198 char buf[ERRMAX];
200 switch(pid = fork()){
201 case -1:
202 return -1;
203 case 0:
204 pushword("exec");
205 execexec();
206 strcpy(buf, "can't exec: ");
207 n = strlen(buf);
208 errstr(buf+n, ERRMAX-n);
209 Exit(buf);
211 return pid;