plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

haventfork.c (3122B)


      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 void
     55 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;
     65 
     66 	stop = ifs->val?ifs->val->word:"";
     67 	if(pipe(pfd)<0){
     68 		Xerror("can't make pipe");
     69 		return;
     70 	}
     71 
     72 	Updenv();
     73 
     74 	argv = rcargv(runq->code[runq->pc].s);
     75 	pid = ForkExecute(argv0, argv, -1, pfd[1], 2);
     76 	free(argv);
     77 
     78 	close(pfd[1]);
     79 
     80 	if(pid == 0) {
     81 		Xerror("proc failed");
     82 		close(pfd[0]);
     83 		return;
     84 	}
     85 
     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 }
    114 
    115 void
    116 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;
    123 
    124 	if(pipe(pfd)<0){
    125 		Xerror1("can't get pipe");
    126 		return;
    127 	}
    128 
    129 	Updenv();
    130 
    131 	argv = rcargv(runq->code[pc+2].s);
    132 	pid = ForkExecute(argv0, argv, 0, pfd[1], 2);
    133 	free(argv);
    134 	close(pfd[1]);
    135 
    136 	if(pid == 0) {
    137 		Xerror("proc failed");
    138 		close(pfd[0]);
    139 		return;
    140 	}
    141 
    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 }
    147 
    148 void
    149 Xpipefd(void)
    150 {
    151 	Abort();
    152 }
    153 
    154 void
    155 Xsubshell(void)
    156 {
    157 	char **argv;
    158 	int pid;
    159 
    160 	Updenv();
    161 
    162 	argv = rcargv(runq->code[runq->pc].s);
    163 	pid = ForkExecute(argv0, argv, -1, 1, 2);
    164 	free(argv);
    165 
    166 	if(pid < 0) {
    167 		Xerror("proc failed");
    168 		return;
    169 	}
    170 
    171 	Waitfor(pid, 1);
    172 	runq->pc++;
    173 }
    174 
    175 /*
    176  *  start a process running the cmd on the stack and return its pid.
    177  */
    178 int
    179 execforkexec(void)
    180 {
    181 	char **argv;
    182 	char file[1024];
    183 	int nc;
    184 	word *path;
    185 	int pid;
    186 
    187 	if(runq->argv->words==0)
    188 		return -1;
    189 	argv = mkargv(runq->argv->words);
    190 
    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 }