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