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