| haventfork.c - 9base - revived minimalist port of Plan 9 userland to Unix | |
| git clone git://git.suckless.org/9base | |
| Log | |
| Files | |
| Refs | |
| README | |
| LICENSE | |
| --- | |
| 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-… | |
| 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)… | |
| 221 if(pid >= 0){ | |
| 222 free(argv); | |
| 223 return pid; | |
| 224 } | |
| 225 } | |
| 226 } | |
| 227 } | |
| 228 free(argv); | |
| 229 return -1; | |
| 230 } |