#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;}
#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 - 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;
}