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