Blob
1 #include "rc.h"2 #include "getflags.h"3 #include "exec.h"4 #include "io.h"5 #include "fns.h"7 int havefork = 1;9 void10 Xasync(void)11 {12 int null = open("/dev/null", 0);13 int pid;14 char npid[10];15 if(null<0){16 Xerror("Can't open /dev/null\n");17 return;18 }19 switch(pid = rfork(RFFDG|RFPROC|RFNOTEG)){20 case -1:21 close(null);22 Xerror("try again");23 break;24 case 0:25 pushredir(ROPEN, null, 0);26 start(runq->code, runq->pc+1, runq->local);27 runq->ret = 0;28 break;29 default:30 close(null);31 runq->pc = runq->code[runq->pc].i;32 inttoascii(npid, pid);33 setvar("apid", newword(npid, (word *)0));34 break;35 }36 }38 void39 Xpipe(void)40 {41 struct thread *p = runq;42 int pc = p->pc, forkid;43 int lfd = p->code[pc++].i;44 int rfd = p->code[pc++].i;45 int pfd[2];46 if(pipe(pfd)<0){47 Xerror("can't get pipe");48 return;49 }50 switch(forkid = fork()){51 case -1:52 Xerror("try again");53 break;54 case 0:55 start(p->code, pc+2, runq->local);56 runq->ret = 0;57 close(pfd[PRD]);58 pushredir(ROPEN, pfd[PWR], lfd);59 break;60 default:61 start(p->code, p->code[pc].i, runq->local);62 close(pfd[PWR]);63 pushredir(ROPEN, pfd[PRD], rfd);64 p->pc = p->code[pc+1].i;65 p->pid = forkid;66 break;67 }68 }70 /*71 * Who should wait for the exit from the fork?72 */73 void74 Xbackq(void)75 {76 char wd[8193];77 int c;78 char *s, *ewd=&wd[8192], *stop;79 struct io *f;80 var *ifs = vlook("ifs");81 word *v, *nextv;82 int pfd[2];83 int pid;84 stop = ifs->val?ifs->val->word:"";85 if(pipe(pfd)<0){86 Xerror("can't make pipe");87 return;88 }89 switch(pid = fork()){90 case -1:91 Xerror("try again");92 close(pfd[PRD]);93 close(pfd[PWR]);94 return;95 case 0:96 close(pfd[PRD]);97 start(runq->code, runq->pc+1, runq->local);98 pushredir(ROPEN, pfd[PWR], 1);99 return;100 default:101 close(pfd[PWR]);102 f = openfd(pfd[PRD]);103 s = wd;104 v = 0;105 while((c = rchr(f))!=EOF){106 if(strchr(stop, c) || s==ewd){107 if(s!=wd){108 *s='\0';109 v = newword(wd, v);110 s = wd;111 }112 }113 else *s++=c;114 }115 if(s!=wd){116 *s='\0';117 v = newword(wd, v);118 }119 closeio(f);120 Waitfor(pid, 0);121 /* v points to reversed arglist -- reverse it onto argv */122 while(v){123 nextv = v->next;124 v->next = runq->argv->words;125 runq->argv->words = v;126 v = nextv;127 }128 runq->pc = runq->code[runq->pc].i;129 return;130 }131 }133 void134 Xpipefd(void)135 {136 struct thread *p = runq;137 int pc = p->pc;138 char name[40];139 int pfd[2];140 int sidefd, mainfd;141 if(pipe(pfd)<0){142 Xerror("can't get pipe");143 return;144 }145 if(p->code[pc].i==READ){146 sidefd = pfd[PWR];147 mainfd = pfd[PRD];148 }149 else{150 sidefd = pfd[PRD];151 mainfd = pfd[PWR];152 }153 switch(fork()){154 case -1:155 Xerror("try again");156 break;157 case 0:158 start(p->code, pc+2, runq->local);159 close(mainfd);160 pushredir(ROPEN, sidefd, p->code[pc].i==READ?1:0);161 runq->ret = 0;162 break;163 default:164 close(sidefd);165 pushredir(ROPEN, mainfd, mainfd); /* isn't this a noop? */166 strcpy(name, Fdprefix);167 inttoascii(name+strlen(name), mainfd);168 pushword(name);169 p->pc = p->code[pc+1].i;170 break;171 }172 }174 void175 Xsubshell(void)176 {177 int pid;178 switch(pid = fork()){179 case -1:180 Xerror("try again");181 break;182 case 0:183 start(runq->code, runq->pc+1, runq->local);184 runq->ret = 0;185 break;186 default:187 Waitfor(pid, 1);188 runq->pc = runq->code[runq->pc].i;189 break;190 }191 }193 int194 execforkexec(void)195 {196 int pid;197 int n;198 char buf[ERRMAX];200 switch(pid = fork()){201 case -1:202 return -1;203 case 0:204 pushword("exec");205 execexec();206 strcpy(buf, "can't exec: ");207 n = strlen(buf);208 errstr(buf+n, ERRMAX-n);209 Exit(buf);210 }211 return pid;212 }