rminnichmerge57758a716 years agoHistory
211 lines · 3.1 KB · C
RawDownload
#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;} voidXasync(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));} voidXbackq(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++;} voidXpipe(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;} voidXpipefd(void){	Abort();} voidXsubshell(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. */intexecforkexec(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 - 1){	/* 1 for / */			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;}