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 = 0; 8*dc5a79c1SDavid du Colombier 9*dc5a79c1SDavid du Colombier static char ** 10*dc5a79c1SDavid du Colombier rcargv(char *s) 11*dc5a79c1SDavid du Colombier { 12*dc5a79c1SDavid du Colombier int argc; 13*dc5a79c1SDavid du Colombier char **argv; 14*dc5a79c1SDavid du Colombier word *p; 15*dc5a79c1SDavid du Colombier 16*dc5a79c1SDavid du Colombier p = vlook("*")->val; 17*dc5a79c1SDavid du Colombier argv = malloc((count(p)+6)*sizeof(char*)); 18*dc5a79c1SDavid du Colombier argc = 0; 19*dc5a79c1SDavid du Colombier argv[argc++] = argv0; 20*dc5a79c1SDavid du Colombier if(flag['e']) 21*dc5a79c1SDavid du Colombier argv[argc++] = "-Se"; 22*dc5a79c1SDavid du Colombier else 23*dc5a79c1SDavid du Colombier argv[argc++] = "-S"; 24*dc5a79c1SDavid du Colombier argv[argc++] = "-c"; 25*dc5a79c1SDavid du Colombier argv[argc++] = s; 26*dc5a79c1SDavid du Colombier for(p = vlook("*")->val; p; p = p->next) 27*dc5a79c1SDavid du Colombier argv[argc++] = p->word; 28*dc5a79c1SDavid du Colombier argv[argc] = 0; 29*dc5a79c1SDavid du Colombier return argv; 30*dc5a79c1SDavid du Colombier } 31*dc5a79c1SDavid du Colombier 32*dc5a79c1SDavid du Colombier void 33*dc5a79c1SDavid du Colombier Xasync(void) 34*dc5a79c1SDavid du Colombier { 35*dc5a79c1SDavid du Colombier uint pid; 36*dc5a79c1SDavid du Colombier char buf[20], **argv; 37*dc5a79c1SDavid du Colombier 38*dc5a79c1SDavid du Colombier Updenv(); 39*dc5a79c1SDavid du Colombier 40*dc5a79c1SDavid du Colombier argv = rcargv(runq->code[runq->pc].s); 41*dc5a79c1SDavid du Colombier pid = ForkExecute(argv0, argv, -1, 1, 2); 42*dc5a79c1SDavid du Colombier free(argv); 43*dc5a79c1SDavid du Colombier 44*dc5a79c1SDavid du Colombier if(pid == 0) { 45*dc5a79c1SDavid du Colombier Xerror("proc failed"); 46*dc5a79c1SDavid du Colombier return; 47*dc5a79c1SDavid du Colombier } 48*dc5a79c1SDavid du Colombier 49*dc5a79c1SDavid du Colombier runq->pc++; 50*dc5a79c1SDavid du Colombier sprint(buf, "%d", pid); 51*dc5a79c1SDavid du Colombier setvar("apid", newword(buf, (word *)0)); 52*dc5a79c1SDavid du Colombier } 53*dc5a79c1SDavid du Colombier 54*dc5a79c1SDavid du Colombier void 55*dc5a79c1SDavid du Colombier Xbackq(void) 56*dc5a79c1SDavid du Colombier { 57*dc5a79c1SDavid du Colombier char wd[8193], **argv; 58*dc5a79c1SDavid du Colombier int c; 59*dc5a79c1SDavid du Colombier char *s, *ewd=&wd[8192], *stop; 60*dc5a79c1SDavid du Colombier struct io *f; 61*dc5a79c1SDavid du Colombier var *ifs = vlook("ifs"); 62*dc5a79c1SDavid du Colombier word *v, *nextv; 63*dc5a79c1SDavid du Colombier int pfd[2]; 64*dc5a79c1SDavid du Colombier int pid; 65*dc5a79c1SDavid du Colombier 66*dc5a79c1SDavid du Colombier stop = ifs->val?ifs->val->word:""; 67*dc5a79c1SDavid du Colombier if(pipe(pfd)<0){ 68*dc5a79c1SDavid du Colombier Xerror("can't make pipe"); 69*dc5a79c1SDavid du Colombier return; 70*dc5a79c1SDavid du Colombier } 71*dc5a79c1SDavid du Colombier 72*dc5a79c1SDavid du Colombier Updenv(); 73*dc5a79c1SDavid du Colombier 74*dc5a79c1SDavid du Colombier argv = rcargv(runq->code[runq->pc].s); 75*dc5a79c1SDavid du Colombier pid = ForkExecute(argv0, argv, -1, pfd[1], 2); 76*dc5a79c1SDavid du Colombier free(argv); 77*dc5a79c1SDavid du Colombier 78*dc5a79c1SDavid du Colombier close(pfd[1]); 79*dc5a79c1SDavid du Colombier 80*dc5a79c1SDavid du Colombier if(pid == 0) { 81*dc5a79c1SDavid du Colombier Xerror("proc failed"); 82*dc5a79c1SDavid du Colombier close(pfd[0]); 83*dc5a79c1SDavid du Colombier return; 84*dc5a79c1SDavid du Colombier } 85*dc5a79c1SDavid du Colombier 86*dc5a79c1SDavid du Colombier f = openfd(pfd[0]); 87*dc5a79c1SDavid du Colombier s = wd; 88*dc5a79c1SDavid du Colombier v = 0; 89*dc5a79c1SDavid du Colombier while((c=rchr(f))!=EOF){ 90*dc5a79c1SDavid du Colombier if(strchr(stop, c) || s==ewd){ 91*dc5a79c1SDavid du Colombier if(s!=wd){ 92*dc5a79c1SDavid du Colombier *s='\0'; 93*dc5a79c1SDavid du Colombier v=newword(wd, v); 94*dc5a79c1SDavid du Colombier s=wd; 95*dc5a79c1SDavid du Colombier } 96*dc5a79c1SDavid du Colombier } 97*dc5a79c1SDavid du Colombier else *s++=c; 98*dc5a79c1SDavid du Colombier } 99*dc5a79c1SDavid du Colombier if(s!=wd){ 100*dc5a79c1SDavid du Colombier *s='\0'; 101*dc5a79c1SDavid du Colombier v=newword(wd, v); 102*dc5a79c1SDavid du Colombier } 103*dc5a79c1SDavid du Colombier closeio(f); 104*dc5a79c1SDavid du Colombier Waitfor(pid, 1); 105*dc5a79c1SDavid du Colombier /* v points to reversed arglist -- reverse it onto argv */ 106*dc5a79c1SDavid du Colombier while(v){ 107*dc5a79c1SDavid du Colombier nextv=v->next; 108*dc5a79c1SDavid du Colombier v->next=runq->argv->words; 109*dc5a79c1SDavid du Colombier runq->argv->words=v; 110*dc5a79c1SDavid du Colombier v=nextv; 111*dc5a79c1SDavid du Colombier } 112*dc5a79c1SDavid du Colombier runq->pc++; 113*dc5a79c1SDavid du Colombier } 114*dc5a79c1SDavid du Colombier 115*dc5a79c1SDavid du Colombier void 116*dc5a79c1SDavid du Colombier Xpipe(void) 117*dc5a79c1SDavid du Colombier { 118*dc5a79c1SDavid du Colombier thread *p=runq; 119*dc5a79c1SDavid du Colombier int pc=p->pc, pid; 120*dc5a79c1SDavid du Colombier int rfd=p->code[pc+1].i; 121*dc5a79c1SDavid du Colombier int pfd[2]; 122*dc5a79c1SDavid du Colombier char **argv; 123*dc5a79c1SDavid du Colombier 124*dc5a79c1SDavid du Colombier if(pipe(pfd)<0){ 125*dc5a79c1SDavid du Colombier Xerror1("can't get pipe"); 126*dc5a79c1SDavid du Colombier return; 127*dc5a79c1SDavid du Colombier } 128*dc5a79c1SDavid du Colombier 129*dc5a79c1SDavid du Colombier Updenv(); 130*dc5a79c1SDavid du Colombier 131*dc5a79c1SDavid du Colombier argv = rcargv(runq->code[pc+2].s); 132*dc5a79c1SDavid du Colombier pid = ForkExecute(argv0, argv, 0, pfd[1], 2); 133*dc5a79c1SDavid du Colombier free(argv); 134*dc5a79c1SDavid du Colombier close(pfd[1]); 135*dc5a79c1SDavid du Colombier 136*dc5a79c1SDavid du Colombier if(pid == 0) { 137*dc5a79c1SDavid du Colombier Xerror("proc failed"); 138*dc5a79c1SDavid du Colombier close(pfd[0]); 139*dc5a79c1SDavid du Colombier return; 140*dc5a79c1SDavid du Colombier } 141*dc5a79c1SDavid du Colombier 142*dc5a79c1SDavid du Colombier start(p->code, pc+4, runq->local); 143*dc5a79c1SDavid du Colombier pushredir(ROPEN, pfd[0], rfd); 144*dc5a79c1SDavid du Colombier p->pc=p->code[pc+3].i; 145*dc5a79c1SDavid du Colombier p->pid=pid; 146*dc5a79c1SDavid du Colombier } 147*dc5a79c1SDavid du Colombier 148*dc5a79c1SDavid du Colombier void 149*dc5a79c1SDavid du Colombier Xpipefd(void) 150*dc5a79c1SDavid du Colombier { 151*dc5a79c1SDavid du Colombier Abort(); 152*dc5a79c1SDavid du Colombier } 153*dc5a79c1SDavid du Colombier 154*dc5a79c1SDavid du Colombier void 155*dc5a79c1SDavid du Colombier Xsubshell(void) 156*dc5a79c1SDavid du Colombier { 157*dc5a79c1SDavid du Colombier char **argv; 158*dc5a79c1SDavid du Colombier int pid; 159*dc5a79c1SDavid du Colombier 160*dc5a79c1SDavid du Colombier Updenv(); 161*dc5a79c1SDavid du Colombier 162*dc5a79c1SDavid du Colombier argv = rcargv(runq->code[runq->pc].s); 163*dc5a79c1SDavid du Colombier pid = ForkExecute(argv0, argv, -1, 1, 2); 164*dc5a79c1SDavid du Colombier free(argv); 165*dc5a79c1SDavid du Colombier 166*dc5a79c1SDavid du Colombier if(pid < 0) { 167*dc5a79c1SDavid du Colombier Xerror("proc failed"); 168*dc5a79c1SDavid du Colombier return; 169*dc5a79c1SDavid du Colombier } 170*dc5a79c1SDavid du Colombier 171*dc5a79c1SDavid du Colombier Waitfor(pid, 1); 172*dc5a79c1SDavid du Colombier runq->pc++; 173*dc5a79c1SDavid du Colombier } 174*dc5a79c1SDavid du Colombier 175*dc5a79c1SDavid du Colombier /* 176*dc5a79c1SDavid du Colombier * start a process running the cmd on the stack and return its pid. 177*dc5a79c1SDavid du Colombier */ 178*dc5a79c1SDavid du Colombier int 179*dc5a79c1SDavid du Colombier execforkexec(void) 180*dc5a79c1SDavid du Colombier { 181*dc5a79c1SDavid du Colombier char **argv; 182*dc5a79c1SDavid du Colombier char file[1024]; 183*dc5a79c1SDavid du Colombier int nc; 184*dc5a79c1SDavid du Colombier word *path; 185*dc5a79c1SDavid du Colombier int pid; 186*dc5a79c1SDavid du Colombier 187*dc5a79c1SDavid du Colombier if(runq->argv->words==0) 188*dc5a79c1SDavid du Colombier return -1; 189*dc5a79c1SDavid du Colombier argv = mkargv(runq->argv->words); 190*dc5a79c1SDavid du Colombier 191*dc5a79c1SDavid du Colombier for(path = searchpath(runq->argv->words->word);path;path = path->next){ 192*dc5a79c1SDavid du Colombier nc = strlen(path->word); 193*dc5a79c1SDavid du Colombier if(nc<sizeof(file)){ 194*dc5a79c1SDavid du Colombier strcpy(file, path->word); 195*dc5a79c1SDavid du Colombier if(file[0]){ 196*dc5a79c1SDavid du Colombier strcat(file, "/"); 197*dc5a79c1SDavid du Colombier nc++; 198*dc5a79c1SDavid du Colombier } 199*dc5a79c1SDavid du Colombier if(nc+strlen(argv[1])<sizeof(file)){ 200*dc5a79c1SDavid du Colombier strcat(file, argv[1]); 201*dc5a79c1SDavid du Colombier pid = ForkExecute(file, argv+1, mapfd(0), mapfd(1), mapfd(2)); 202*dc5a79c1SDavid du Colombier if(pid >= 0){ 203*dc5a79c1SDavid du Colombier free(argv); 204*dc5a79c1SDavid du Colombier return pid; 205*dc5a79c1SDavid du Colombier } 206*dc5a79c1SDavid du Colombier } 207*dc5a79c1SDavid du Colombier } 208*dc5a79c1SDavid du Colombier } 209*dc5a79c1SDavid du Colombier free(argv); 210*dc5a79c1SDavid du Colombier return -1; 211*dc5a79c1SDavid du Colombier } 212