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