| #include "rc.h" |
| #include "getflags.h" |
| #include "exec.h" |
| #include "io.h" |
| #include "fns.h" |
| |
| int havefork = 0; |
| |
| static char ** |
| rcargv(char *s) |
| { |
| int argc; |
| char **argv; |
| word *p; |
| |
| p = vlook("*")->val; |
| argv = malloc((count(p)+6)*sizeof(char*)); |
| argc = 0; |
| argv[argc++] = argv0; |
| if(flag['e']) |
| argv[argc++] = "-Se"; |
| else |
| argv[argc++] = "-S"; |
| argv[argc++] = "-c"; |
| argv[argc++] = s; |
| for(p = vlook("*")->val; p; p = p->next) |
| argv[argc++] = p->word; |
| argv[argc] = 0; |
| return argv; |
| } |
| |
| void |
| Xasync(void) |
| { |
| uint pid; |
| char buf[20], **argv; |
| |
| Updenv(); |
| |
| argv = rcargv(runq->code[runq->pc].s); |
| pid = ForkExecute(argv0, argv, -1, 1, 2); |
| free(argv); |
| |
| if(pid == 0) { |
| Xerror("proc failed"); |
| return; |
| } |
| |
| runq->pc++; |
| sprint(buf, "%d", pid); |
| setvar("apid", newword(buf, (word *)0)); |
| } |
| |
| void |
| Xbackq(void) |
| { |
| char wd[8193], **argv; |
| int c; |
| char *s, *ewd=&wd[8192], *stop; |
| struct io *f; |
| var *ifs = vlook("ifs"); |
| word *v, *nextv; |
| int pfd[2]; |
| int pid; |
| |
| stop = ifs->val?ifs->val->word:""; |
| if(pipe(pfd)<0){ |
| Xerror("can't make pipe"); |
| return; |
| } |
| |
| Updenv(); |
| |
| argv = rcargv(runq->code[runq->pc].s); |
| pid = ForkExecute(argv0, argv, -1, pfd[1], 2); |
| free(argv); |
| |
| close(pfd[1]); |
| |
| if(pid == 0) { |
| Xerror("proc failed"); |
| close(pfd[0]); |
| return; |
| } |
| |
| f = openfd(pfd[0]); |
| s = wd; |
| v = 0; |
| while((c=rchr(f))!=EOF){ |
| if(strchr(stop, c) || s==ewd){ |
| if(s!=wd){ |
| *s='\0'; |
| v=newword(wd, v); |
| s=wd; |
| } |
| } |
| else *s++=c; |
| } |
| if(s!=wd){ |
| *s='\0'; |
| v=newword(wd, v); |
| } |
| closeio(f); |
| Waitfor(pid, 1); |
| /* v points to reversed arglist -- reverse it onto argv */ |
| while(v){ |
| nextv=v->next; |
| v->next=runq->argv->words; |
| runq->argv->words=v; |
| v=nextv; |
| } |
| runq->pc++; |
| } |
| |
| void |
| Xpipe(void) |
| { |
| thread *p=runq; |
| int pc=p->pc, pid; |
| int rfd=p->code[pc+1].i; |
| int pfd[2]; |
| char **argv; |
| |
| if(pipe(pfd)<0){ |
| Xerror1("can't get pipe"); |
| return; |
| } |
| |
| Updenv(); |
| |
| argv = rcargv(runq->code[pc+2].s); |
| pid = ForkExecute(argv0, argv, 0, pfd[1], 2); |
| free(argv); |
| close(pfd[1]); |
| |
| if(pid == 0) { |
| Xerror("proc failed"); |
| close(pfd[0]); |
| return; |
| } |
| |
| start(p->code, pc+4, runq->local); |
| pushredir(ROPEN, pfd[0], rfd); |
| p->pc=p->code[pc+3].i; |
| p->pid=pid; |
| } |
| |
| void |
| Xpipefd(void) |
| { |
| Abort(); |
| } |
| |
| void |
| Xsubshell(void) |
| { |
| char **argv; |
| int pid; |
| |
| Updenv(); |
| |
| argv = rcargv(runq->code[runq->pc].s); |
| pid = ForkExecute(argv0, argv, -1, 1, 2); |
| free(argv); |
| |
| if(pid < 0) { |
| Xerror("proc failed"); |
| return; |
| } |
| |
| Waitfor(pid, 1); |
| runq->pc++; |
| } |
| |
| /* |
| * start a process running the cmd on the stack and return its pid. |
| */ |
| int |
| execforkexec(void) |
| { |
| char **argv; |
| char file[1024]; |
| int nc; |
| word *path; |
| int pid; |
| |
| if(runq->argv->words==0) |
| return -1; |
| argv = mkargv(runq->argv->words); |
| |
| for(path = searchpath(runq->argv->words->word);path;path = path->next){ |
| nc = strlen(path->word); |
| if(nc<sizeof(file)){ |
| strcpy(file, path->word); |
| if(file[0]){ |
| strcat(file, "/"); |
| nc++; |
| } |
| if(nc+strlen(argv[1])<sizeof(file)){ |
| strcat(file, argv[1]); |
| pid = ForkExecute(file, argv+1, mapfd(0), mapfd(1), mapfd(2)); |
| if(pid >= 0){ |
| free(argv); |
| return pid; |
| } |
| } |
| } |
| } |
| free(argv); |
| return -1; |
| } |