Blob
1 #include "rc.h"2 #include "getflags.h"3 #include "exec.h"4 #include "io.h"5 #include "fns.h"7 int havefork = 0;9 static char **10 rcargv(char *s)11 {12 int argc;13 char **argv;14 word *p;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 else23 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 }32 void33 Xasync(void)34 {35 uint pid;36 char buf[20], **argv;38 Updenv();40 argv = rcargv(runq->code[runq->pc].s);41 pid = ForkExecute(argv0, argv, -1, 1, 2);42 free(argv);44 if(pid == 0) {45 Xerror("proc failed");46 return;47 }49 runq->pc++;50 sprint(buf, "%d", pid);51 setvar("apid", newword(buf, (word *)0));52 }54 void55 Xbackq(void)56 {57 char wd[8193], **argv;58 int c;59 char *s, *ewd=&wd[8192], *stop;60 struct io *f;61 var *ifs = vlook("ifs");62 word *v, *nextv;63 int pfd[2];64 int pid;66 stop = ifs->val?ifs->val->word:"";67 if(pipe(pfd)<0){68 Xerror("can't make pipe");69 return;70 }72 Updenv();74 argv = rcargv(runq->code[runq->pc].s);75 pid = ForkExecute(argv0, argv, -1, pfd[1], 2);76 free(argv);78 close(pfd[1]);80 if(pid == 0) {81 Xerror("proc failed");82 close(pfd[0]);83 return;84 }86 f = openfd(pfd[0]);87 s = wd;88 v = 0;89 while((c=rchr(f))!=EOF){90 if(strchr(stop, c) || s==ewd){91 if(s!=wd){92 *s='\0';93 v=newword(wd, v);94 s=wd;95 }96 }97 else *s++=c;98 }99 if(s!=wd){100 *s='\0';101 v=newword(wd, v);102 }103 closeio(f);104 Waitfor(pid, 1);105 /* v points to reversed arglist -- reverse it onto argv */106 while(v){107 nextv=v->next;108 v->next=runq->argv->words;109 runq->argv->words=v;110 v=nextv;111 }112 runq->pc++;113 }115 void116 Xpipe(void)117 {118 thread *p=runq;119 int pc=p->pc, pid;120 int rfd=p->code[pc+1].i;121 int pfd[2];122 char **argv;124 if(pipe(pfd)<0){125 Xerror1("can't get pipe");126 return;127 }129 Updenv();131 argv = rcargv(runq->code[pc+2].s);132 pid = ForkExecute(argv0, argv, 0, pfd[1], 2);133 free(argv);134 close(pfd[1]);136 if(pid == 0) {137 Xerror("proc failed");138 close(pfd[0]);139 return;140 }142 start(p->code, pc+4, runq->local);143 pushredir(ROPEN, pfd[0], rfd);144 p->pc=p->code[pc+3].i;145 p->pid=pid;146 }148 void149 Xpipefd(void)150 {151 Abort();152 }154 void155 Xsubshell(void)156 {157 char **argv;158 int pid;160 Updenv();162 argv = rcargv(runq->code[runq->pc].s);163 pid = ForkExecute(argv0, argv, -1, 1, 2);164 free(argv);166 if(pid < 0) {167 Xerror("proc failed");168 return;169 }171 Waitfor(pid, 1);172 runq->pc++;173 }175 /*176 * start a process running the cmd on the stack and return its pid.177 */178 int179 execforkexec(void)180 {181 char **argv;182 char file[1024];183 int nc;184 word *path;185 int pid;187 if(runq->argv->words==0)188 return -1;189 argv = mkargv(runq->argv->words);191 for(path = searchpath(runq->argv->words->word);path;path = path->next){192 nc = strlen(path->word);193 if(nc<sizeof(file)){194 strcpy(file, path->word);195 if(file[0]){196 strcat(file, "/");197 nc++;198 }199 if(nc+strlen(argv[1])<sizeof(file)){200 strcat(file, argv[1]);201 pid = ForkExecute(file, argv+1, mapfd(0), mapfd(1), mapfd(2));202 if(pid >= 0){203 free(argv);204 return pid;205 }206 }207 }208 }209 free(argv);210 return -1;211 }