Blob


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