123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- #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;
- }
|