Blob


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"
9 int havefork = 1;
11 void
12 Xasync(void)
13 {
14 int null = open("/dev/null", 0);
15 int pid;
16 int tcpgrp, pgrp;
17 char npid[10];
19 if(null<0){
20 Xerror("Can't open /dev/null\n");
21 return;
22 }
23 switch(pid = rfork(RFFDG|RFPROC|RFNOTEG)){
24 case -1:
25 close(null);
26 Xerror("try again");
27 break;
28 case 0:
29 /*
30 * Should make reads of tty fail, writes succeed.
31 */
32 signal(SIGTTIN, SIG_IGN);
33 signal(SIGTTOU, SIG_IGN);
35 pushredir(ROPEN, null, 0);
36 start(runq->code, runq->pc+1, runq->local);
37 runq->ret = 0;
38 break;
39 default:
40 close(null);
41 runq->pc = runq->code[runq->pc].i;
42 inttoascii(npid, pid);
43 setvar("apid", newword(npid, (word *)0));
44 break;
45 }
46 }
48 void
49 Xpipe(void)
50 {
51 struct thread *p = runq;
52 int pc = p->pc, forkid;
53 int lfd = p->code[pc++].i;
54 int rfd = p->code[pc++].i;
55 int pfd[2];
56 if(pipe(pfd)<0){
57 Xerror("can't get pipe");
58 return;
59 }
60 switch(forkid = fork()){
61 case -1:
62 Xerror("try again");
63 break;
64 case 0:
65 start(p->code, pc+2, runq->local);
66 runq->ret = 0;
67 close(pfd[PRD]);
68 pushredir(ROPEN, pfd[PWR], lfd);
69 break;
70 default:
71 start(p->code, p->code[pc].i, runq->local);
72 close(pfd[PWR]);
73 pushredir(ROPEN, pfd[PRD], rfd);
74 p->pc = p->code[pc+1].i;
75 p->pid = forkid;
76 break;
77 }
78 }
80 /*
81 * Who should wait for the exit from the fork?
82 */
83 void
84 Xbackq(void)
85 {
86 char wd[8193];
87 int c;
88 char *s, *ewd=&wd[8192], *stop;
89 struct io *f;
90 var *ifs = vlook("ifs");
91 word *v, *nextv;
92 int pfd[2];
93 int pid;
94 stop = ifs->val?ifs->val->word:"";
95 if(pipe(pfd)<0){
96 Xerror("can't make pipe");
97 return;
98 }
99 switch(pid = fork()){
100 case -1:
101 Xerror("try again");
102 close(pfd[PRD]);
103 close(pfd[PWR]);
104 return;
105 case 0:
106 close(pfd[PRD]);
107 start(runq->code, runq->pc+1, runq->local);
108 pushredir(ROPEN, pfd[PWR], 1);
109 return;
110 default:
111 close(pfd[PWR]);
112 f = openfd(pfd[PRD]);
113 s = wd;
114 v = 0;
115 while((c = rchr(f))!=EOF){
116 if(strchr(stop, c) || s==ewd){
117 if(s!=wd){
118 *s='\0';
119 v = newword(wd, v);
120 s = wd;
123 else *s++=c;
125 if(s!=wd){
126 *s='\0';
127 v = newword(wd, v);
129 closeio(f);
130 Waitfor(pid, 0);
131 /* v points to reversed arglist -- reverse it onto argv */
132 while(v){
133 nextv = v->next;
134 v->next = runq->argv->words;
135 runq->argv->words = v;
136 v = nextv;
138 runq->pc = runq->code[runq->pc].i;
139 return;
143 void
144 Xpipefd(void)
146 struct thread *p = runq;
147 int pc = p->pc;
148 char name[40];
149 int pfd[2];
150 int sidefd, mainfd;
151 if(pipe(pfd)<0){
152 Xerror("can't get pipe");
153 return;
155 if(p->code[pc].i==READ){
156 sidefd = pfd[PWR];
157 mainfd = pfd[PRD];
159 else{
160 sidefd = pfd[PRD];
161 mainfd = pfd[PWR];
163 switch(fork()){
164 case -1:
165 Xerror("try again");
166 break;
167 case 0:
168 start(p->code, pc+2, runq->local);
169 close(mainfd);
170 pushredir(ROPEN, sidefd, p->code[pc].i==READ?1:0);
171 runq->ret = 0;
172 break;
173 default:
174 close(sidefd);
175 pushredir(ROPEN, mainfd, mainfd); /* isn't this a noop? */
176 strcpy(name, Fdprefix);
177 inttoascii(name+strlen(name), mainfd);
178 pushword(name);
179 p->pc = p->code[pc+1].i;
180 break;
184 void
185 Xsubshell(void)
187 int pid;
188 switch(pid = fork()){
189 case -1:
190 Xerror("try again");
191 break;
192 case 0:
193 start(runq->code, runq->pc+1, runq->local);
194 runq->ret = 0;
195 break;
196 default:
197 Waitfor(pid, 1);
198 runq->pc = runq->code[runq->pc].i;
199 break;
203 int
204 execforkexec(void)
206 int pid;
207 int n;
208 char buf[ERRMAX];
210 switch(pid = fork()){
211 case -1:
212 return -1;
213 case 0:
214 pushword("exec");
215 execexec();
216 strcpy(buf, "can't exec: ");
217 n = strlen(buf);
218 errstr(buf+n, ERRMAX-n);
219 Exit(buf);
221 return pid;