diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/rc/haventfork.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/rc/haventfork.c')
-rwxr-xr-x | sys/src/cmd/rc/haventfork.c | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/sys/src/cmd/rc/haventfork.c b/sys/src/cmd/rc/haventfork.c new file mode 100755 index 000000000..a5464ba5b --- /dev/null +++ b/sys/src/cmd/rc/haventfork.c @@ -0,0 +1,211 @@ +#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 - 1){ /* 1 for / */ + 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; +} |