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