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