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: 25d3907fe5SDavid 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: 31d3907fe5SDavid 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: 57d3907fe5SDavid 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: 64d3907fe5SDavid 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 74276e7d6dSDavid du Colombier enum { Wordmax = 8192, }; 75276e7d6dSDavid du Colombier 76dc5a79c1SDavid du Colombier /* 77dc5a79c1SDavid du Colombier * Who should wait for the exit from the fork? 78dc5a79c1SDavid du Colombier */ 79dc5a79c1SDavid du Colombier void 80dc5a79c1SDavid du Colombier Xbackq(void) 81dc5a79c1SDavid du Colombier { 82276e7d6dSDavid du Colombier int c, pid; 83276e7d6dSDavid du Colombier int pfd[2]; 84276e7d6dSDavid du Colombier char wd[Wordmax + 1]; 85276e7d6dSDavid du Colombier char *s, *ewd = &wd[Wordmax], *stop; 86dc5a79c1SDavid du Colombier struct io *f; 87dc5a79c1SDavid du Colombier var *ifs = vlook("ifs"); 88dc5a79c1SDavid du Colombier word *v, *nextv; 89276e7d6dSDavid du Colombier 90dc5a79c1SDavid du Colombier stop = ifs->val? ifs->val->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]); 111dc5a79c1SDavid du Colombier s = wd; 112dc5a79c1SDavid du Colombier v = 0; 113*fbd2c77cSDavid du Colombier /* 114*fbd2c77cSDavid du Colombier * this isn't quite right for utf. stop could have utf 115*fbd2c77cSDavid du Colombier * in it, and we're processing the input as bytes, not 116*fbd2c77cSDavid du Colombier * utf encodings of runes. further, if we run out of 117*fbd2c77cSDavid du Colombier * room in wd, we can chop in the middle of a utf encoding 118*fbd2c77cSDavid du Colombier * (not to mention stepping on one of the bytes). 119*fbd2c77cSDavid du Colombier * presotto's Strings seem like the right data structure here. 120*fbd2c77cSDavid du Colombier */ 121dc5a79c1SDavid du Colombier while((c = rchr(f))!=EOF){ 122dc5a79c1SDavid du Colombier if(strchr(stop, c) || s==ewd){ 123dc5a79c1SDavid du Colombier if(s!=wd){ 124dc5a79c1SDavid du Colombier *s='\0'; 125dc5a79c1SDavid du Colombier v = newword(wd, v); 126dc5a79c1SDavid du Colombier s = wd; 127dc5a79c1SDavid du Colombier } 128dc5a79c1SDavid du Colombier } 12999eb86a7SDavid du Colombier else *s++=c; 130dc5a79c1SDavid du Colombier } 131dc5a79c1SDavid du Colombier if(s!=wd){ 132dc5a79c1SDavid du Colombier *s='\0'; 133dc5a79c1SDavid du Colombier v = newword(wd, v); 134dc5a79c1SDavid du Colombier } 135dc5a79c1SDavid du Colombier closeio(f); 136dc5a79c1SDavid du Colombier Waitfor(pid, 0); 137dc5a79c1SDavid du Colombier /* v points to reversed arglist -- reverse it onto argv */ 138dc5a79c1SDavid du Colombier while(v){ 139dc5a79c1SDavid du Colombier nextv = v->next; 140dc5a79c1SDavid du Colombier v->next = runq->argv->words; 141dc5a79c1SDavid du Colombier runq->argv->words = v; 142dc5a79c1SDavid du Colombier v = nextv; 143dc5a79c1SDavid du Colombier } 144dc5a79c1SDavid du Colombier runq->pc = runq->code[runq->pc].i; 145dc5a79c1SDavid du Colombier return; 146dc5a79c1SDavid du Colombier } 147dc5a79c1SDavid du Colombier } 148dc5a79c1SDavid du Colombier 149dc5a79c1SDavid du Colombier void 150dc5a79c1SDavid du Colombier Xpipefd(void) 151dc5a79c1SDavid du Colombier { 152dc5a79c1SDavid du Colombier struct thread *p = runq; 15399eb86a7SDavid du Colombier int pc = p->pc, pid; 154276e7d6dSDavid du Colombier char name[40]; 15599eb86a7SDavid du Colombier int pfd[2]; 15699eb86a7SDavid du Colombier int sidefd, mainfd; 157dc5a79c1SDavid du Colombier if(pipe(pfd)<0){ 158dc5a79c1SDavid du Colombier Xerror("can't get pipe"); 159dc5a79c1SDavid du Colombier return; 160dc5a79c1SDavid du Colombier } 161dc5a79c1SDavid du Colombier if(p->code[pc].i==READ){ 162dc5a79c1SDavid du Colombier sidefd = pfd[PWR]; 163dc5a79c1SDavid du Colombier mainfd = pfd[PRD]; 164dc5a79c1SDavid du Colombier } 165dc5a79c1SDavid du Colombier else{ 166dc5a79c1SDavid du Colombier sidefd = pfd[PRD]; 167dc5a79c1SDavid du Colombier mainfd = pfd[PWR]; 168dc5a79c1SDavid du Colombier } 169d3907fe5SDavid du Colombier switch(pid = fork()){ 170dc5a79c1SDavid du Colombier case -1: 171dc5a79c1SDavid du Colombier Xerror("try again"); 172dc5a79c1SDavid du Colombier break; 173dc5a79c1SDavid du Colombier case 0: 174d3907fe5SDavid du Colombier clearwaitpids(); 175dc5a79c1SDavid du Colombier start(p->code, pc+2, runq->local); 176dc5a79c1SDavid du Colombier close(mainfd); 177dc5a79c1SDavid du Colombier pushredir(ROPEN, sidefd, p->code[pc].i==READ?1:0); 178dc5a79c1SDavid du Colombier runq->ret = 0; 179dc5a79c1SDavid du Colombier break; 180dc5a79c1SDavid du Colombier default: 181d3907fe5SDavid du Colombier addwaitpid(pid); 182dc5a79c1SDavid du Colombier close(sidefd); 183dc5a79c1SDavid du Colombier pushredir(ROPEN, mainfd, mainfd); /* isn't this a noop? */ 184dc5a79c1SDavid du Colombier strcpy(name, Fdprefix); 185dc5a79c1SDavid du Colombier inttoascii(name+strlen(name), mainfd); 186dc5a79c1SDavid du Colombier pushword(name); 187dc5a79c1SDavid du Colombier p->pc = p->code[pc+1].i; 188dc5a79c1SDavid du Colombier break; 189dc5a79c1SDavid du Colombier } 190dc5a79c1SDavid du Colombier } 191dc5a79c1SDavid du Colombier 192dc5a79c1SDavid du Colombier void 193dc5a79c1SDavid du Colombier Xsubshell(void) 194dc5a79c1SDavid du Colombier { 195dc5a79c1SDavid du Colombier int pid; 196dc5a79c1SDavid du Colombier switch(pid = fork()){ 197dc5a79c1SDavid du Colombier case -1: 198dc5a79c1SDavid du Colombier Xerror("try again"); 199dc5a79c1SDavid du Colombier break; 200dc5a79c1SDavid du Colombier case 0: 201d3907fe5SDavid du Colombier clearwaitpids(); 202dc5a79c1SDavid du Colombier start(runq->code, runq->pc+1, runq->local); 203dc5a79c1SDavid du Colombier runq->ret = 0; 204dc5a79c1SDavid du Colombier break; 205dc5a79c1SDavid du Colombier default: 206d3907fe5SDavid du Colombier addwaitpid(pid); 207dc5a79c1SDavid du Colombier Waitfor(pid, 1); 208dc5a79c1SDavid du Colombier runq->pc = runq->code[runq->pc].i; 209dc5a79c1SDavid du Colombier break; 210dc5a79c1SDavid du Colombier } 211dc5a79c1SDavid du Colombier } 212dc5a79c1SDavid du Colombier 213dc5a79c1SDavid du Colombier int 214dc5a79c1SDavid du Colombier execforkexec(void) 215dc5a79c1SDavid du Colombier { 216dc5a79c1SDavid du Colombier int pid; 217dc5a79c1SDavid du Colombier int n; 218dc5a79c1SDavid du Colombier char buf[ERRMAX]; 219dc5a79c1SDavid du Colombier 220dc5a79c1SDavid du Colombier switch(pid = fork()){ 221dc5a79c1SDavid du Colombier case -1: 222dc5a79c1SDavid du Colombier return -1; 223dc5a79c1SDavid du Colombier case 0: 224d3907fe5SDavid du Colombier clearwaitpids(); 225dc5a79c1SDavid du Colombier pushword("exec"); 226dc5a79c1SDavid du Colombier execexec(); 227dc5a79c1SDavid du Colombier strcpy(buf, "can't exec: "); 228dc5a79c1SDavid du Colombier n = strlen(buf); 229dc5a79c1SDavid du Colombier errstr(buf+n, ERRMAX-n); 230dc5a79c1SDavid du Colombier Exit(buf); 231dc5a79c1SDavid du Colombier } 232d3907fe5SDavid du Colombier addwaitpid(pid); 233dc5a79c1SDavid du Colombier return pid; 234dc5a79c1SDavid du Colombier } 235