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