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