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