| #include "rc.h" | 
 | #include "getflags.h" | 
 | #include "exec.h" | 
 | #include "io.h" | 
 | #include "fns.h" | 
 |  | 
 | int havefork = 0; | 
 |  | 
 | static char ** | 
 | rcargv(char *s) | 
 | { | 
 | 	int argc; | 
 | 	char **argv; | 
 | 	word *p; | 
 |  | 
 | 	p = vlook("*")->val; | 
 | 	argv = malloc((count(p)+6)*sizeof(char*)); | 
 | 	argc = 0; | 
 | 	argv[argc++] = argv0; | 
 | 	if(flag['e']) | 
 | 		argv[argc++] = "-Se"; | 
 | 	else | 
 | 		argv[argc++] = "-S"; | 
 | 	argv[argc++] = "-c"; | 
 | 	argv[argc++] = s; | 
 | 	for(p = vlook("*")->val; p; p = p->next) | 
 | 		argv[argc++] = p->word; | 
 | 	argv[argc] = 0; | 
 | 	return argv; | 
 | } | 
 |  | 
 | void | 
 | Xasync(void) | 
 | { | 
 | 	uint pid; | 
 | 	char buf[20], **argv; | 
 |  | 
 | 	Updenv(); | 
 |  | 
 | 	argv = rcargv(runq->code[runq->pc].s); | 
 | 	pid = ForkExecute(argv0, argv, -1, 1, 2); | 
 | 	free(argv); | 
 |  | 
 | 	if(pid == 0) { | 
 | 		Xerror("proc failed"); | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	runq->pc++; | 
 | 	sprint(buf, "%d", pid); | 
 | 	setvar("apid", newword(buf, (word *)0)); | 
 | } | 
 |  | 
 | void | 
 | Xbackq(void) | 
 | { | 
 | 	char wd[8193], **argv; | 
 | 	int c; | 
 | 	char *s, *ewd=&wd[8192], *stop; | 
 | 	struct io *f; | 
 | 	var *ifs = vlook("ifs"); | 
 | 	word *v, *nextv; | 
 | 	int pfd[2]; | 
 | 	int pid; | 
 |  | 
 | 	stop = ifs->val?ifs->val->word:""; | 
 | 	if(pipe(pfd)<0){ | 
 | 		Xerror("can't make pipe"); | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	Updenv(); | 
 |  | 
 | 	argv = rcargv(runq->code[runq->pc].s); | 
 | 	pid = ForkExecute(argv0, argv, -1, pfd[1], 2); | 
 | 	free(argv); | 
 |  | 
 | 	close(pfd[1]); | 
 |  | 
 | 	if(pid == 0) { | 
 | 		Xerror("proc failed"); | 
 | 		close(pfd[0]); | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	f = openfd(pfd[0]); | 
 | 	s = wd; | 
 | 	v = 0; | 
 | 	while((c=rchr(f))!=EOF){ | 
 | 		if(strchr(stop, c) || s==ewd){ | 
 | 			if(s!=wd){ | 
 | 				*s='\0'; | 
 | 				v=newword(wd, v); | 
 | 				s=wd; | 
 | 			} | 
 | 		} | 
 | 		else *s++=c; | 
 | 	} | 
 | 	if(s!=wd){ | 
 | 		*s='\0'; | 
 | 		v=newword(wd, v); | 
 | 	} | 
 | 	closeio(f); | 
 | 	Waitfor(pid, 1); | 
 | 	/* v points to reversed arglist -- reverse it onto argv */ | 
 | 	while(v){ | 
 | 		nextv=v->next; | 
 | 		v->next=runq->argv->words; | 
 | 		runq->argv->words=v; | 
 | 		v=nextv; | 
 | 	} | 
 | 	runq->pc++; | 
 | } | 
 |  | 
 | void | 
 | Xpipe(void) | 
 | { | 
 | 	thread *p=runq; | 
 | 	int pc=p->pc, pid; | 
 | 	int rfd=p->code[pc+1].i; | 
 | 	int pfd[2]; | 
 | 	char **argv; | 
 |  | 
 | 	if(pipe(pfd)<0){ | 
 | 		Xerror1("can't get pipe"); | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	Updenv(); | 
 |  | 
 | 	argv = rcargv(runq->code[pc+2].s); | 
 | 	pid = ForkExecute(argv0, argv, 0, pfd[1], 2); | 
 | 	free(argv); | 
 | 	close(pfd[1]); | 
 |  | 
 | 	if(pid == 0) { | 
 | 		Xerror("proc failed"); | 
 | 		close(pfd[0]); | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	start(p->code, pc+4, runq->local); | 
 | 	pushredir(ROPEN, pfd[0], rfd); | 
 | 	p->pc=p->code[pc+3].i; | 
 | 	p->pid=pid; | 
 | } | 
 |  | 
 | void | 
 | Xpipefd(void) | 
 | { | 
 | 	Abort(); | 
 | } | 
 |  | 
 | void | 
 | Xsubshell(void) | 
 | { | 
 | 	char **argv; | 
 | 	int pid; | 
 |  | 
 | 	Updenv(); | 
 |  | 
 | 	argv = rcargv(runq->code[runq->pc].s); | 
 | 	pid = ForkExecute(argv0, argv, -1, 1, 2); | 
 | 	free(argv); | 
 |  | 
 | 	if(pid < 0) { | 
 | 		Xerror("proc failed"); | 
 | 		return; | 
 | 	} | 
 |  | 
 | 	Waitfor(pid, 1); | 
 | 	runq->pc++; | 
 | } | 
 |  | 
 | /* | 
 |  *  start a process running the cmd on the stack and return its pid. | 
 |  */ | 
 | int | 
 | execforkexec(void) | 
 | { | 
 | 	char **argv; | 
 | 	char file[1024]; | 
 | 	int nc; | 
 | 	word *path; | 
 | 	int pid; | 
 |  | 
 | 	if(runq->argv->words==0) | 
 | 		return -1; | 
 | 	argv = mkargv(runq->argv->words); | 
 |  | 
 | 	for(path = searchpath(runq->argv->words->word);path;path = path->next){ | 
 | 		nc = strlen(path->word); | 
 | 		if(nc<sizeof(file)){ | 
 | 			strcpy(file, path->word); | 
 | 			if(file[0]){ | 
 | 				strcat(file, "/"); | 
 | 				nc++; | 
 | 			} | 
 | 			if(nc+strlen(argv[1])<sizeof(file)){ | 
 | 				strcat(file, argv[1]); | 
 | 				pid = ForkExecute(file, argv+1, mapfd(0), mapfd(1), mapfd(2)); | 
 | 				if(pid >= 0){ | 
 | 					free(argv); | 
 | 					return pid; | 
 | 				} | 
 | 			} | 
 | 		} | 
 | 	} | 
 | 	free(argv); | 
 | 	return -1; | 
 | } |