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