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