haventfork.c (3122B)
1 #include "rc.h" 2 #include "getflags.h" 3 #include "exec.h" 4 #include "io.h" 5 #include "fns.h" 6 7 int havefork = 0; 8 9 static char ** 10 rcargv(char *s) 11 { 12 int argc; 13 char **argv; 14 word *p; 15 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 } 31 32 void 33 Xasync(void) 34 { 35 uint pid; 36 char buf[20], **argv; 37 38 Updenv(); 39 40 argv = rcargv(runq->code[runq->pc].s); 41 pid = ForkExecute(argv0, argv, -1, 1, 2); 42 free(argv); 43 44 if(pid == 0) { 45 Xerror("proc failed"); 46 return; 47 } 48 49 runq->pc++; 50 sprint(buf, "%d", pid); 51 setvar("apid", newword(buf, (word *)0)); 52 } 53 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; 65 66 stop = ifs->val?ifs->val->word:""; 67 if(pipe(pfd)<0){ 68 Xerror("can't make pipe"); 69 return; 70 } 71 72 Updenv(); 73 74 argv = rcargv(runq->code[runq->pc].s); 75 pid = ForkExecute(argv0, argv, -1, pfd[1], 2); 76 free(argv); 77 78 close(pfd[1]); 79 80 if(pid == 0) { 81 Xerror("proc failed"); 82 close(pfd[0]); 83 return; 84 } 85 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); 102 } 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; 111 } 112 runq->pc++; 113 } 114 115 void 116 Xpipe(void) 117 { 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; 123 124 if(pipe(pfd)<0){ 125 Xerror1("can't get pipe"); 126 return; 127 } 128 129 Updenv(); 130 131 argv = rcargv(runq->code[pc+2].s); 132 pid = ForkExecute(argv0, argv, 0, pfd[1], 2); 133 free(argv); 134 close(pfd[1]); 135 136 if(pid == 0) { 137 Xerror("proc failed"); 138 close(pfd[0]); 139 return; 140 } 141 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; 146 } 147 148 void 149 Xpipefd(void) 150 { 151 Abort(); 152 } 153 154 void 155 Xsubshell(void) 156 { 157 char **argv; 158 int pid; 159 160 Updenv(); 161 162 argv = rcargv(runq->code[runq->pc].s); 163 pid = ForkExecute(argv0, argv, -1, 1, 2); 164 free(argv); 165 166 if(pid < 0) { 167 Xerror("proc failed"); 168 return; 169 } 170 171 Waitfor(pid, 1); 172 runq->pc++; 173 } 174 175 /* 176 * start a process running the cmd on the stack and return its pid. 177 */ 178 int 179 execforkexec(void) 180 { 181 char **argv; 182 char file[1024]; 183 int nc; 184 word *path; 185 int pid; 186 187 if(runq->argv->words==0) 188 return -1; 189 argv = mkargv(runq->argv->words); 190 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++; 198 } 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; 205 } 206 } 207 } 208 } 209 free(argv); 210 return -1; 211 }