xref: /plan9/sys/src/cmd/rc/haventfork.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 = 0;
8*dc5a79c1SDavid du Colombier 
9*dc5a79c1SDavid du Colombier static char **
10*dc5a79c1SDavid du Colombier rcargv(char *s)
11*dc5a79c1SDavid du Colombier {
12*dc5a79c1SDavid du Colombier 	int argc;
13*dc5a79c1SDavid du Colombier 	char **argv;
14*dc5a79c1SDavid du Colombier 	word *p;
15*dc5a79c1SDavid du Colombier 
16*dc5a79c1SDavid du Colombier 	p = vlook("*")->val;
17*dc5a79c1SDavid du Colombier 	argv = malloc((count(p)+6)*sizeof(char*));
18*dc5a79c1SDavid du Colombier 	argc = 0;
19*dc5a79c1SDavid du Colombier 	argv[argc++] = argv0;
20*dc5a79c1SDavid du Colombier 	if(flag['e'])
21*dc5a79c1SDavid du Colombier 		argv[argc++] = "-Se";
22*dc5a79c1SDavid du Colombier 	else
23*dc5a79c1SDavid du Colombier 		argv[argc++] = "-S";
24*dc5a79c1SDavid du Colombier 	argv[argc++] = "-c";
25*dc5a79c1SDavid du Colombier 	argv[argc++] = s;
26*dc5a79c1SDavid du Colombier 	for(p = vlook("*")->val; p; p = p->next)
27*dc5a79c1SDavid du Colombier 		argv[argc++] = p->word;
28*dc5a79c1SDavid du Colombier 	argv[argc] = 0;
29*dc5a79c1SDavid du Colombier 	return argv;
30*dc5a79c1SDavid du Colombier }
31*dc5a79c1SDavid du Colombier 
32*dc5a79c1SDavid du Colombier void
33*dc5a79c1SDavid du Colombier Xasync(void)
34*dc5a79c1SDavid du Colombier {
35*dc5a79c1SDavid du Colombier 	uint pid;
36*dc5a79c1SDavid du Colombier 	char buf[20], **argv;
37*dc5a79c1SDavid du Colombier 
38*dc5a79c1SDavid du Colombier 	Updenv();
39*dc5a79c1SDavid du Colombier 
40*dc5a79c1SDavid du Colombier 	argv = rcargv(runq->code[runq->pc].s);
41*dc5a79c1SDavid du Colombier 	pid = ForkExecute(argv0, argv, -1, 1, 2);
42*dc5a79c1SDavid du Colombier 	free(argv);
43*dc5a79c1SDavid du Colombier 
44*dc5a79c1SDavid du Colombier 	if(pid == 0) {
45*dc5a79c1SDavid du Colombier 		Xerror("proc failed");
46*dc5a79c1SDavid du Colombier 		return;
47*dc5a79c1SDavid du Colombier 	}
48*dc5a79c1SDavid du Colombier 
49*dc5a79c1SDavid du Colombier 	runq->pc++;
50*dc5a79c1SDavid du Colombier 	sprint(buf, "%d", pid);
51*dc5a79c1SDavid du Colombier 	setvar("apid", newword(buf, (word *)0));
52*dc5a79c1SDavid du Colombier }
53*dc5a79c1SDavid du Colombier 
54*dc5a79c1SDavid du Colombier void
55*dc5a79c1SDavid du Colombier Xbackq(void)
56*dc5a79c1SDavid du Colombier {
57*dc5a79c1SDavid du Colombier 	char wd[8193], **argv;
58*dc5a79c1SDavid du Colombier 	int c;
59*dc5a79c1SDavid du Colombier 	char *s, *ewd=&wd[8192], *stop;
60*dc5a79c1SDavid du Colombier 	struct io *f;
61*dc5a79c1SDavid du Colombier 	var *ifs = vlook("ifs");
62*dc5a79c1SDavid du Colombier 	word *v, *nextv;
63*dc5a79c1SDavid du Colombier 	int pfd[2];
64*dc5a79c1SDavid du Colombier 	int pid;
65*dc5a79c1SDavid du Colombier 
66*dc5a79c1SDavid du Colombier 	stop = ifs->val?ifs->val->word:"";
67*dc5a79c1SDavid du Colombier 	if(pipe(pfd)<0){
68*dc5a79c1SDavid du Colombier 		Xerror("can't make pipe");
69*dc5a79c1SDavid du Colombier 		return;
70*dc5a79c1SDavid du Colombier 	}
71*dc5a79c1SDavid du Colombier 
72*dc5a79c1SDavid du Colombier 	Updenv();
73*dc5a79c1SDavid du Colombier 
74*dc5a79c1SDavid du Colombier 	argv = rcargv(runq->code[runq->pc].s);
75*dc5a79c1SDavid du Colombier 	pid = ForkExecute(argv0, argv, -1, pfd[1], 2);
76*dc5a79c1SDavid du Colombier 	free(argv);
77*dc5a79c1SDavid du Colombier 
78*dc5a79c1SDavid du Colombier 	close(pfd[1]);
79*dc5a79c1SDavid du Colombier 
80*dc5a79c1SDavid du Colombier 	if(pid == 0) {
81*dc5a79c1SDavid du Colombier 		Xerror("proc failed");
82*dc5a79c1SDavid du Colombier 		close(pfd[0]);
83*dc5a79c1SDavid du Colombier 		return;
84*dc5a79c1SDavid du Colombier 	}
85*dc5a79c1SDavid du Colombier 
86*dc5a79c1SDavid du Colombier 	f = openfd(pfd[0]);
87*dc5a79c1SDavid du Colombier 	s = wd;
88*dc5a79c1SDavid du Colombier 	v = 0;
89*dc5a79c1SDavid du Colombier 	while((c=rchr(f))!=EOF){
90*dc5a79c1SDavid du Colombier 		if(strchr(stop, c) || s==ewd){
91*dc5a79c1SDavid du Colombier 			if(s!=wd){
92*dc5a79c1SDavid du Colombier 				*s='\0';
93*dc5a79c1SDavid du Colombier 				v=newword(wd, v);
94*dc5a79c1SDavid du Colombier 				s=wd;
95*dc5a79c1SDavid du Colombier 			}
96*dc5a79c1SDavid du Colombier 		}
97*dc5a79c1SDavid du Colombier 		else *s++=c;
98*dc5a79c1SDavid du Colombier 	}
99*dc5a79c1SDavid du Colombier 	if(s!=wd){
100*dc5a79c1SDavid du Colombier 		*s='\0';
101*dc5a79c1SDavid du Colombier 		v=newword(wd, v);
102*dc5a79c1SDavid du Colombier 	}
103*dc5a79c1SDavid du Colombier 	closeio(f);
104*dc5a79c1SDavid du Colombier 	Waitfor(pid, 1);
105*dc5a79c1SDavid du Colombier 	/* v points to reversed arglist -- reverse it onto argv */
106*dc5a79c1SDavid du Colombier 	while(v){
107*dc5a79c1SDavid du Colombier 		nextv=v->next;
108*dc5a79c1SDavid du Colombier 		v->next=runq->argv->words;
109*dc5a79c1SDavid du Colombier 		runq->argv->words=v;
110*dc5a79c1SDavid du Colombier 		v=nextv;
111*dc5a79c1SDavid du Colombier 	}
112*dc5a79c1SDavid du Colombier 	runq->pc++;
113*dc5a79c1SDavid du Colombier }
114*dc5a79c1SDavid du Colombier 
115*dc5a79c1SDavid du Colombier void
116*dc5a79c1SDavid du Colombier Xpipe(void)
117*dc5a79c1SDavid du Colombier {
118*dc5a79c1SDavid du Colombier 	thread *p=runq;
119*dc5a79c1SDavid du Colombier 	int pc=p->pc, pid;
120*dc5a79c1SDavid du Colombier 	int rfd=p->code[pc+1].i;
121*dc5a79c1SDavid du Colombier 	int pfd[2];
122*dc5a79c1SDavid du Colombier 	char **argv;
123*dc5a79c1SDavid du Colombier 
124*dc5a79c1SDavid du Colombier 	if(pipe(pfd)<0){
125*dc5a79c1SDavid du Colombier 		Xerror1("can't get pipe");
126*dc5a79c1SDavid du Colombier 		return;
127*dc5a79c1SDavid du Colombier 	}
128*dc5a79c1SDavid du Colombier 
129*dc5a79c1SDavid du Colombier 	Updenv();
130*dc5a79c1SDavid du Colombier 
131*dc5a79c1SDavid du Colombier 	argv = rcargv(runq->code[pc+2].s);
132*dc5a79c1SDavid du Colombier 	pid = ForkExecute(argv0, argv, 0, pfd[1], 2);
133*dc5a79c1SDavid du Colombier 	free(argv);
134*dc5a79c1SDavid du Colombier 	close(pfd[1]);
135*dc5a79c1SDavid du Colombier 
136*dc5a79c1SDavid du Colombier 	if(pid == 0) {
137*dc5a79c1SDavid du Colombier 		Xerror("proc failed");
138*dc5a79c1SDavid du Colombier 		close(pfd[0]);
139*dc5a79c1SDavid du Colombier 		return;
140*dc5a79c1SDavid du Colombier 	}
141*dc5a79c1SDavid du Colombier 
142*dc5a79c1SDavid du Colombier 	start(p->code, pc+4, runq->local);
143*dc5a79c1SDavid du Colombier 	pushredir(ROPEN, pfd[0], rfd);
144*dc5a79c1SDavid du Colombier 	p->pc=p->code[pc+3].i;
145*dc5a79c1SDavid du Colombier 	p->pid=pid;
146*dc5a79c1SDavid du Colombier }
147*dc5a79c1SDavid du Colombier 
148*dc5a79c1SDavid du Colombier void
149*dc5a79c1SDavid du Colombier Xpipefd(void)
150*dc5a79c1SDavid du Colombier {
151*dc5a79c1SDavid du Colombier 	Abort();
152*dc5a79c1SDavid du Colombier }
153*dc5a79c1SDavid du Colombier 
154*dc5a79c1SDavid du Colombier void
155*dc5a79c1SDavid du Colombier Xsubshell(void)
156*dc5a79c1SDavid du Colombier {
157*dc5a79c1SDavid du Colombier 	char **argv;
158*dc5a79c1SDavid du Colombier 	int pid;
159*dc5a79c1SDavid du Colombier 
160*dc5a79c1SDavid du Colombier 	Updenv();
161*dc5a79c1SDavid du Colombier 
162*dc5a79c1SDavid du Colombier 	argv = rcargv(runq->code[runq->pc].s);
163*dc5a79c1SDavid du Colombier 	pid = ForkExecute(argv0, argv, -1, 1, 2);
164*dc5a79c1SDavid du Colombier 	free(argv);
165*dc5a79c1SDavid du Colombier 
166*dc5a79c1SDavid du Colombier 	if(pid < 0) {
167*dc5a79c1SDavid du Colombier 		Xerror("proc failed");
168*dc5a79c1SDavid du Colombier 		return;
169*dc5a79c1SDavid du Colombier 	}
170*dc5a79c1SDavid du Colombier 
171*dc5a79c1SDavid du Colombier 	Waitfor(pid, 1);
172*dc5a79c1SDavid du Colombier 	runq->pc++;
173*dc5a79c1SDavid du Colombier }
174*dc5a79c1SDavid du Colombier 
175*dc5a79c1SDavid du Colombier /*
176*dc5a79c1SDavid du Colombier  *  start a process running the cmd on the stack and return its pid.
177*dc5a79c1SDavid du Colombier  */
178*dc5a79c1SDavid du Colombier int
179*dc5a79c1SDavid du Colombier execforkexec(void)
180*dc5a79c1SDavid du Colombier {
181*dc5a79c1SDavid du Colombier 	char **argv;
182*dc5a79c1SDavid du Colombier 	char file[1024];
183*dc5a79c1SDavid du Colombier 	int nc;
184*dc5a79c1SDavid du Colombier 	word *path;
185*dc5a79c1SDavid du Colombier 	int pid;
186*dc5a79c1SDavid du Colombier 
187*dc5a79c1SDavid du Colombier 	if(runq->argv->words==0)
188*dc5a79c1SDavid du Colombier 		return -1;
189*dc5a79c1SDavid du Colombier 	argv = mkargv(runq->argv->words);
190*dc5a79c1SDavid du Colombier 
191*dc5a79c1SDavid du Colombier 	for(path = searchpath(runq->argv->words->word);path;path = path->next){
192*dc5a79c1SDavid du Colombier 		nc = strlen(path->word);
193*dc5a79c1SDavid du Colombier 		if(nc<sizeof(file)){
194*dc5a79c1SDavid du Colombier 			strcpy(file, path->word);
195*dc5a79c1SDavid du Colombier 			if(file[0]){
196*dc5a79c1SDavid du Colombier 				strcat(file, "/");
197*dc5a79c1SDavid du Colombier 				nc++;
198*dc5a79c1SDavid du Colombier 			}
199*dc5a79c1SDavid du Colombier 			if(nc+strlen(argv[1])<sizeof(file)){
200*dc5a79c1SDavid du Colombier 				strcat(file, argv[1]);
201*dc5a79c1SDavid du Colombier 				pid = ForkExecute(file, argv+1, mapfd(0), mapfd(1), mapfd(2));
202*dc5a79c1SDavid du Colombier 				if(pid >= 0){
203*dc5a79c1SDavid du Colombier 					free(argv);
204*dc5a79c1SDavid du Colombier 					return pid;
205*dc5a79c1SDavid du Colombier 				}
206*dc5a79c1SDavid du Colombier 			}
207*dc5a79c1SDavid du Colombier 		}
208*dc5a79c1SDavid du Colombier 	}
209*dc5a79c1SDavid du Colombier 	free(argv);
210*dc5a79c1SDavid du Colombier 	return -1;
211*dc5a79c1SDavid du Colombier }
212