1dc5a79c1SDavid du Colombier #include "rc.h" 2dc5a79c1SDavid du Colombier #include "exec.h" 3dc5a79c1SDavid du Colombier #include "io.h" 4dc5a79c1SDavid du Colombier #include "fns.h" 5dc5a79c1SDavid du Colombier 6dc5a79c1SDavid du Colombier int havefork = 1; 7dc5a79c1SDavid du Colombier 8dc5a79c1SDavid du Colombier void 9dc5a79c1SDavid du Colombier Xasync(void) 10dc5a79c1SDavid du Colombier { 11dc5a79c1SDavid du Colombier int null = open("/dev/null", 0); 12dc5a79c1SDavid du Colombier int pid; 13dc5a79c1SDavid du Colombier char npid[10]; 14dc5a79c1SDavid du Colombier if(null<0){ 15dc5a79c1SDavid du Colombier Xerror("Can't open /dev/null\n"); 16dc5a79c1SDavid du Colombier return; 17dc5a79c1SDavid du Colombier } 1875ac14c9SDavid du Colombier switch(pid = rfork(RFFDG|RFPROC|RFNOTEG)){ 19dc5a79c1SDavid du Colombier case -1: 20dc5a79c1SDavid du Colombier close(null); 21dc5a79c1SDavid du Colombier Xerror("try again"); 22dc5a79c1SDavid du Colombier break; 23dc5a79c1SDavid du Colombier case 0: 24d3907fe5SDavid du Colombier clearwaitpids(); 25dc5a79c1SDavid du Colombier pushredir(ROPEN, null, 0); 26dc5a79c1SDavid du Colombier start(runq->code, runq->pc+1, runq->local); 27dc5a79c1SDavid du Colombier runq->ret = 0; 28dc5a79c1SDavid du Colombier break; 29dc5a79c1SDavid du Colombier default: 30d3907fe5SDavid du Colombier addwaitpid(pid); 31dc5a79c1SDavid du Colombier close(null); 32dc5a79c1SDavid du Colombier runq->pc = runq->code[runq->pc].i; 33dc5a79c1SDavid du Colombier inttoascii(npid, pid); 34dc5a79c1SDavid du Colombier setvar("apid", newword(npid, (word *)0)); 35dc5a79c1SDavid du Colombier break; 36dc5a79c1SDavid du Colombier } 37dc5a79c1SDavid du Colombier } 38dc5a79c1SDavid du Colombier 39dc5a79c1SDavid du Colombier void 40dc5a79c1SDavid du Colombier Xpipe(void) 41dc5a79c1SDavid du Colombier { 42dc5a79c1SDavid du Colombier struct thread *p = runq; 43dc5a79c1SDavid du Colombier int pc = p->pc, forkid; 44dc5a79c1SDavid du Colombier int lfd = p->code[pc++].i; 45dc5a79c1SDavid du Colombier int rfd = p->code[pc++].i; 46dc5a79c1SDavid du Colombier int pfd[2]; 47dc5a79c1SDavid du Colombier if(pipe(pfd)<0){ 48dc5a79c1SDavid du Colombier Xerror("can't get pipe"); 49dc5a79c1SDavid du Colombier return; 50dc5a79c1SDavid du Colombier } 51dc5a79c1SDavid du Colombier switch(forkid = fork()){ 52dc5a79c1SDavid du Colombier case -1: 53dc5a79c1SDavid du Colombier Xerror("try again"); 54dc5a79c1SDavid du Colombier break; 55dc5a79c1SDavid du Colombier case 0: 56d3907fe5SDavid du Colombier clearwaitpids(); 57dc5a79c1SDavid du Colombier start(p->code, pc+2, runq->local); 58dc5a79c1SDavid du Colombier runq->ret = 0; 59dc5a79c1SDavid du Colombier close(pfd[PRD]); 60dc5a79c1SDavid du Colombier pushredir(ROPEN, pfd[PWR], lfd); 61dc5a79c1SDavid du Colombier break; 62dc5a79c1SDavid du Colombier default: 63d3907fe5SDavid du Colombier addwaitpid(forkid); 64dc5a79c1SDavid du Colombier start(p->code, p->code[pc].i, runq->local); 65dc5a79c1SDavid du Colombier close(pfd[PWR]); 66dc5a79c1SDavid du Colombier pushredir(ROPEN, pfd[PRD], rfd); 67dc5a79c1SDavid du Colombier p->pc = p->code[pc+1].i; 68dc5a79c1SDavid du Colombier p->pid = forkid; 69dc5a79c1SDavid du Colombier break; 70dc5a79c1SDavid du Colombier } 71dc5a79c1SDavid du Colombier } 72dc5a79c1SDavid du Colombier 73dc5a79c1SDavid du Colombier /* 74dc5a79c1SDavid du Colombier * Who should wait for the exit from the fork? 75dc5a79c1SDavid du Colombier */ 768cc1c73aSDavid du Colombier 77dc5a79c1SDavid du Colombier void 78dc5a79c1SDavid du Colombier Xbackq(void) 79dc5a79c1SDavid du Colombier { 808cc1c73aSDavid du Colombier int n, pid; 81276e7d6dSDavid du Colombier int pfd[2]; 828cc1c73aSDavid du Colombier char *stop; 838cc1c73aSDavid du Colombier char utf[UTFmax+1]; 84c6df1444SDavid du Colombier io *f, *wd; 85dc5a79c1SDavid du Colombier word *v, *nextv; 868cc1c73aSDavid du Colombier Rune r; 87276e7d6dSDavid du Colombier 88*dbee7877SDavid du Colombier stop = ""; 89*dbee7877SDavid du Colombier if(runq->argv && runq->argv->words) 90*dbee7877SDavid du Colombier stop = runq->argv->words->word; 91dc5a79c1SDavid du Colombier if(pipe(pfd)<0){ 92dc5a79c1SDavid du Colombier Xerror("can't make pipe"); 93dc5a79c1SDavid du Colombier return; 94dc5a79c1SDavid du Colombier } 95dc5a79c1SDavid du Colombier switch(pid = fork()){ 96dc5a79c1SDavid du Colombier case -1: 97dc5a79c1SDavid du Colombier Xerror("try again"); 98dc5a79c1SDavid du Colombier close(pfd[PRD]); 99dc5a79c1SDavid du Colombier close(pfd[PWR]); 100dc5a79c1SDavid du Colombier return; 101dc5a79c1SDavid du Colombier case 0: 102d3907fe5SDavid du Colombier clearwaitpids(); 103dc5a79c1SDavid du Colombier close(pfd[PRD]); 104dc5a79c1SDavid du Colombier start(runq->code, runq->pc+1, runq->local); 105dc5a79c1SDavid du Colombier pushredir(ROPEN, pfd[PWR], 1); 106dc5a79c1SDavid du Colombier return; 107dc5a79c1SDavid du Colombier default: 108d3907fe5SDavid du Colombier addwaitpid(pid); 109dc5a79c1SDavid du Colombier close(pfd[PWR]); 110dc5a79c1SDavid du Colombier f = openfd(pfd[PRD]); 111c6df1444SDavid du Colombier wd = openstr(); 1128cc1c73aSDavid du Colombier v = nil; 1138cc1c73aSDavid du Colombier /* rutf requires at least UTFmax+1 bytes in utf */ 1148cc1c73aSDavid du Colombier while((n = rutf(f, utf, &r)) != EOF){ 1158cc1c73aSDavid du Colombier utf[n] = '\0'; 1168cc1c73aSDavid du Colombier if(utfutf(stop, utf) == nil) 117c6df1444SDavid du Colombier pstr(wd, utf); /* append utf to word */ 1188cc1c73aSDavid du Colombier else 119fbd2c77cSDavid du Colombier /* 1208cc1c73aSDavid du Colombier * utf/r is an ifs rune (e.g., \t, \n), thus 1218cc1c73aSDavid du Colombier * ends the current word, if any. 122fbd2c77cSDavid du Colombier */ 123c6df1444SDavid du Colombier if(*(char *)wd->strp != '\0'){ 124c6df1444SDavid du Colombier v = newword((char *)wd->strp, v); 125c6df1444SDavid du Colombier rewind(wd); 126dc5a79c1SDavid du Colombier } 127dc5a79c1SDavid du Colombier } 128c6df1444SDavid du Colombier if(*(char *)wd->strp != '\0') 129c6df1444SDavid du Colombier v = newword((char *)wd->strp, v); 130c6df1444SDavid du Colombier closeio(wd); 131dc5a79c1SDavid du Colombier closeio(f); 132dc5a79c1SDavid du Colombier Waitfor(pid, 0); 133*dbee7877SDavid du Colombier poplist(); /* ditch split in "stop" */ 134dc5a79c1SDavid du Colombier /* v points to reversed arglist -- reverse it onto argv */ 135dc5a79c1SDavid du Colombier while(v){ 136dc5a79c1SDavid du Colombier nextv = v->next; 137dc5a79c1SDavid du Colombier v->next = runq->argv->words; 138dc5a79c1SDavid du Colombier runq->argv->words = v; 139dc5a79c1SDavid du Colombier v = nextv; 140dc5a79c1SDavid du Colombier } 141dc5a79c1SDavid du Colombier runq->pc = runq->code[runq->pc].i; 142dc5a79c1SDavid du Colombier return; 143dc5a79c1SDavid du Colombier } 144dc5a79c1SDavid du Colombier } 145dc5a79c1SDavid du Colombier 146dc5a79c1SDavid du Colombier void 147dc5a79c1SDavid du Colombier Xpipefd(void) 148dc5a79c1SDavid du Colombier { 149dc5a79c1SDavid du Colombier struct thread *p = runq; 15099eb86a7SDavid du Colombier int pc = p->pc, pid; 151276e7d6dSDavid du Colombier char name[40]; 15299eb86a7SDavid du Colombier int pfd[2]; 15399eb86a7SDavid du Colombier int sidefd, mainfd; 154dc5a79c1SDavid du Colombier if(pipe(pfd)<0){ 155dc5a79c1SDavid du Colombier Xerror("can't get pipe"); 156dc5a79c1SDavid du Colombier return; 157dc5a79c1SDavid du Colombier } 158dc5a79c1SDavid du Colombier if(p->code[pc].i==READ){ 159dc5a79c1SDavid du Colombier sidefd = pfd[PWR]; 160dc5a79c1SDavid du Colombier mainfd = pfd[PRD]; 161dc5a79c1SDavid du Colombier } 162dc5a79c1SDavid du Colombier else{ 163dc5a79c1SDavid du Colombier sidefd = pfd[PRD]; 164dc5a79c1SDavid du Colombier mainfd = pfd[PWR]; 165dc5a79c1SDavid du Colombier } 166d3907fe5SDavid du Colombier switch(pid = fork()){ 167dc5a79c1SDavid du Colombier case -1: 168dc5a79c1SDavid du Colombier Xerror("try again"); 169dc5a79c1SDavid du Colombier break; 170dc5a79c1SDavid du Colombier case 0: 171d3907fe5SDavid du Colombier clearwaitpids(); 172dc5a79c1SDavid du Colombier start(p->code, pc+2, runq->local); 173dc5a79c1SDavid du Colombier close(mainfd); 174dc5a79c1SDavid du Colombier pushredir(ROPEN, sidefd, p->code[pc].i==READ?1:0); 175dc5a79c1SDavid du Colombier runq->ret = 0; 176dc5a79c1SDavid du Colombier break; 177dc5a79c1SDavid du Colombier default: 178d3907fe5SDavid du Colombier addwaitpid(pid); 179dc5a79c1SDavid du Colombier close(sidefd); 180dc5a79c1SDavid du Colombier pushredir(ROPEN, mainfd, mainfd); /* isn't this a noop? */ 181dc5a79c1SDavid du Colombier strcpy(name, Fdprefix); 182dc5a79c1SDavid du Colombier inttoascii(name+strlen(name), mainfd); 183dc5a79c1SDavid du Colombier pushword(name); 184dc5a79c1SDavid du Colombier p->pc = p->code[pc+1].i; 185dc5a79c1SDavid du Colombier break; 186dc5a79c1SDavid du Colombier } 187dc5a79c1SDavid du Colombier } 188dc5a79c1SDavid du Colombier 189dc5a79c1SDavid du Colombier void 190dc5a79c1SDavid du Colombier Xsubshell(void) 191dc5a79c1SDavid du Colombier { 192dc5a79c1SDavid du Colombier int pid; 193dc5a79c1SDavid du Colombier switch(pid = fork()){ 194dc5a79c1SDavid du Colombier case -1: 195dc5a79c1SDavid du Colombier Xerror("try again"); 196dc5a79c1SDavid du Colombier break; 197dc5a79c1SDavid du Colombier case 0: 198d3907fe5SDavid du Colombier clearwaitpids(); 199dc5a79c1SDavid du Colombier start(runq->code, runq->pc+1, runq->local); 200dc5a79c1SDavid du Colombier runq->ret = 0; 201dc5a79c1SDavid du Colombier break; 202dc5a79c1SDavid du Colombier default: 203d3907fe5SDavid du Colombier addwaitpid(pid); 204dc5a79c1SDavid du Colombier Waitfor(pid, 1); 205dc5a79c1SDavid du Colombier runq->pc = runq->code[runq->pc].i; 206dc5a79c1SDavid du Colombier break; 207dc5a79c1SDavid du Colombier } 208dc5a79c1SDavid du Colombier } 209dc5a79c1SDavid du Colombier 210dc5a79c1SDavid du Colombier int 211dc5a79c1SDavid du Colombier execforkexec(void) 212dc5a79c1SDavid du Colombier { 213dc5a79c1SDavid du Colombier int pid; 214dc5a79c1SDavid du Colombier int n; 215dc5a79c1SDavid du Colombier char buf[ERRMAX]; 216dc5a79c1SDavid du Colombier 217dc5a79c1SDavid du Colombier switch(pid = fork()){ 218dc5a79c1SDavid du Colombier case -1: 219dc5a79c1SDavid du Colombier return -1; 220dc5a79c1SDavid du Colombier case 0: 221d3907fe5SDavid du Colombier clearwaitpids(); 222dc5a79c1SDavid du Colombier pushword("exec"); 223dc5a79c1SDavid du Colombier execexec(); 224dc5a79c1SDavid du Colombier strcpy(buf, "can't exec: "); 225dc5a79c1SDavid du Colombier n = strlen(buf); 226dc5a79c1SDavid du Colombier errstr(buf+n, ERRMAX-n); 227dc5a79c1SDavid du Colombier Exit(buf); 228dc5a79c1SDavid du Colombier } 229d3907fe5SDavid du Colombier addwaitpid(pid); 230dc5a79c1SDavid du Colombier return pid; 231dc5a79c1SDavid du Colombier } 232