mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-15 11:20:03 +00:00
f08fdedcee
not a clear win over byron's, but at least it has the right syntax.
211 lines
3 KiB
C
211 lines
3 KiB
C
#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;
|
|
}
|