diff options
author | rsc <devnull@localhost> | 2003-11-23 18:04:08 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2003-11-23 18:04:08 +0000 |
commit | f08fdedcee12c06e3ce9ac9bec363915978e8289 (patch) | |
tree | d67a27473be1e8f98d3694028104d9ddf915345b /src/cmd/rc/haventfork.c | |
parent | 5993a8f2756bc455101a8c9ce95347d5050e7883 (diff) | |
download | plan9port-f08fdedcee12c06e3ce9ac9bec363915978e8289.tar.gz plan9port-f08fdedcee12c06e3ce9ac9bec363915978e8289.tar.bz2 plan9port-f08fdedcee12c06e3ce9ac9bec363915978e8289.zip |
Plan 9's rc.
not a clear win over byron's,
but at least it has the right syntax.
Diffstat (limited to 'src/cmd/rc/haventfork.c')
-rw-r--r-- | src/cmd/rc/haventfork.c | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/src/cmd/rc/haventfork.c b/src/cmd/rc/haventfork.c new file mode 100644 index 00000000..fc8f7608 --- /dev/null +++ b/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)){ + 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; +} |