#include <u.h>
#include <signal.h>
#if defined(PLAN9PORT) && defined(__sun__)
#	define BSD_COMP	/* sigh.  for TIOCNOTTY */
#endif
#include <sys/ioctl.h>
#include "rc.h"
#include "getflags.h"
#include "exec.h"
#include "io.h"
#include "fns.h"
/*
 * Start executing the given code at the given pc with the given redirection
 */
char *argv0="rc";
void start(code *c, int pc, var *local)
{
	struct thread *p=new(struct thread);
	p->code=codecopy(c);
	p->pc=pc;
	p->argv=0;
	p->redir=p->startredir=runq?runq->redir:0;
	p->local=local;
	p->cmdfile=0;
	p->cmdfd=0;
	p->eof=0;
	p->iflag=0;
	p->lineno=1;
	p->pid=-1;
	p->ret=runq;
	runq=p;
}
word *newword(char *wd, word *next)
{
	word *p=new(word);
	p->word=strdup(wd);
	p->next=next;
	return p;
}
void pushword(char *wd)
{
	if(runq->argv==0) panic("pushword but no argv!", 0);
	runq->argv->words=newword(wd, runq->argv->words);
}
void popword(void){
	word *p;
	if(runq->argv==0) panic("popword but no argv!", 0);
	p=runq->argv->words;
	if(p==0) panic("popword but no word!", 0);
	runq->argv->words=p->next;
	efree(p->word);
	efree((char *)p);
}
void freelist(word *w)
{
	word *nw;
	while(w){
		nw=w->next;
		efree(w->word);
		efree((char *)w);
		w=nw;
	}
}
void pushlist(void){
	list *p=new(list);
	p->next=runq->argv;
	p->words=0;
	runq->argv=p;
}
void poplist(void){
	list *p=runq->argv;
	if(p==0) panic("poplist but no argv", 0);
	freelist(p->words);
	runq->argv=p->next;
	efree((char *)p);
}
int count(word *w)
{
	int n;
	for(n=0;w;n++) w=w->next;
	return n;
}
void pushredir(int type, int from, int to){
	redir * rp=new(redir);
	rp->type=type;
	rp->from=from;
	rp->to=to;
	rp->next=runq->redir;
	runq->redir=rp;
}
var *newvar(char *name, var *next)
{
	var *v=new(var);
	v->name=name;
	v->val=0;
	v->fn=0;
	v->changed=0;
	v->fnchanged=0;
	v->next=next;
	v->changefn = 0;
	return v;
}
/*
 * get command line flags, initialize keywords & traps.
 * get values from environment.
 * set $pid, $cflag, $*
 * fabricate bootstrap code and start it (*=(argv);. /usr/lib/rcmain $*)
 * start interpreting code
 */
int
main(int argc, char *argv[])
{
	code bootstrap[32];
	char num[12], *rcmain;
	int i;
	
	/* needed for rcmain later */
	putenv("PLAN9", unsharp("#9"));

	argc=getflags(argc, argv, "srdiIlxepvVc:1m:1[command]", 1);
	if(argc==-1) usage("[file [arg ...]]");
	if(argv[0][0]=='-') flag['l']=flagset;
	if(flag['I']) flag['i'] = 0;
	else if(flag['i']==0 && argc==1 && Isatty(0)) flag['i'] = flagset;
	rcmain=flag['m']?flag['m'][0]:Rcmain(); 
	err=openfd(2);
	kinit();
	Trapinit();
	Vinit();
	itoa(num, mypid=getpid());
	pathinit();
	setvar("pid", newword(num, (word *)0));
	setvar("cflag", flag['c']?newword(flag['c'][0], (word *)0)
				:(word *)0);
	setvar("rcname", newword(argv[0], (word *)0));
	i=0;
	bootstrap[i++].i=1;
	bootstrap[i++].f=Xmark;
	bootstrap[i++].f=Xword;
	bootstrap[i++].s="*";
	bootstrap[i++].f=Xassign;
	bootstrap[i++].f=Xmark;
	bootstrap[i++].f=Xmark;
	bootstrap[i++].f=Xword;
	bootstrap[i++].s="*";
	bootstrap[i++].f=Xdol;
	bootstrap[i++].f=Xword;
	bootstrap[i++].s=rcmain;
	bootstrap[i++].f=Xword;
	bootstrap[i++].s=".";
	bootstrap[i++].f=Xsimple;
	bootstrap[i++].f=Xexit;
	bootstrap[i].i=0;
	start(bootstrap, 1, (var *)0);
	/* prime bootstrap argv */
	pushlist();
	argv0 = strdup(argv[0]);
	for(i=argc-1;i!=0;--i) pushword(argv[i]);
	for(;;){
		if(flag['r']) pfnc(err, runq);
		runq->pc++;
		(*runq->code[runq->pc-1].f)();
		if(ntrap) dotrap();
	}
}
/*
 * Opcode routines
 * Arguments on stack (...)
 * Arguments in line [...]
 * Code in line with jump around {...}
 *
 * Xappend(file)[fd]			open file to append
 * Xassign(name, val)			assign val to name
 * Xasync{... Xexit}			make thread for {}, no wait
 * Xbackq{... Xreturn}			make thread for {}, push stdout
 * Xbang				complement condition
 * Xcase(pat, value){...}		exec code on match, leave (value) on
 * 					stack
 * Xclose[i]				close file descriptor
 * Xconc(left, right)			concatenate, push results
 * Xcount(name)				push var count
 * Xdelfn(name)				delete function definition
 * Xdeltraps(names)			delete named traps
 * Xdol(name)				get variable value
 * Xqdol(name)				concatenate variable components
 * Xdup[i j]				dup file descriptor
 * Xexit				rc exits with status
 * Xfalse{...}				execute {} if false
 * Xfn(name){... Xreturn}			define function
 * Xfor(var, list){... Xreturn}		for loop
 * Xjump[addr]				goto
 * Xlocal(name, val)			create local variable, assign value
 * Xmark				mark stack
 * Xmatch(pat, str)			match pattern, set status
 * Xpipe[i j]{... Xreturn}{... Xreturn}	construct a pipe between 2 new threads,
 * 					wait for both
 * Xpipefd[type]{... Xreturn}		connect {} to pipe (input or output,
 * 					depending on type), push /dev/fd/??
 * Xpopm(value)				pop value from stack
 * Xread(file)[fd]			open file to read
 * Xsettraps(names){... Xreturn}		define trap functions
 * Xshowtraps				print trap list
 * Xsimple(args)			run command and wait
 * Xreturn				kill thread
 * Xsubshell{... Xexit}			execute {} in a subshell and wait
 * Xtrue{...}				execute {} if true
 * Xunlocal				delete local variable
 * Xword[string]			push string
 * Xwrite(file)[fd]			open file to write
 */
void Xappend(void){
	char *file;
	int f;
	switch(count(runq->argv->words)){
	default: Xerror1(">> requires singleton"); return;
	case 0: Xerror1(">> requires file"); return;
	case 1: break;
	}
	file=runq->argv->words->word;
	if((f=open(file, 1))<0 && (f=Creat(file))<0){
		pfmt(err, "%s: ", file);
		Xerror("can't open");
		return;
	}
	Seek(f, 0L, 2);
	pushredir(ROPEN, f, runq->code[runq->pc].i);
	runq->pc++;
	poplist();
}
void Xasync(void){
	int null=open("/dev/null", 0);
	int tty;
	int pid;
	char npid[10];
	if(null<0){
		Xerror("Can't open /dev/null\n");
		return;
	}
	switch(pid=rfork(RFFDG|RFPROC|RFNOTEG)){
	case -1:
		close(null);
		Xerror("try again");
		break;
	case 0:
		/*
		 * I don't know what the right thing to do here is,
		 * so this is all experimentally determined.
		 * If we just dup /dev/null onto 0, then running
		 * ssh foo & will reopen /dev/tty, try to read a password,
		 * get a signal, and repeat, in a tight loop, forever.
		 * Arguably this is a bug in ssh (it behaves the same
		 * way under bash as under rc) but I'm fixing it here 
		 * anyway.  If we dissociate the process from the tty,
		 * then it won't be able to open /dev/tty ever again.
		 * The SIG_IGN on SIGTTOU makes writing the tty
		 * (via fd 1 or 2, for example) succeed even though 
		 * our pgrp is not the terminal's controlling pgrp.
		 */
		if((tty=open("/dev/tty", OREAD)) >= 0){
			/*
			 * Should make reads of tty fail, writes succeed.
			 */
			signal(SIGTTIN, SIG_IGN);
			signal(SIGTTOU, SIG_IGN);
			ioctl(tty, TIOCNOTTY);
			close(tty);
		}
		if(isatty(0))
			pushredir(ROPEN, null, 0);
		else
			close(null);
		start(runq->code, runq->pc+1, runq->local);
		runq->ret=0;
		break;
	default:
		close(null);
		runq->pc=runq->code[runq->pc].i;
		itoa(npid, pid);
		setvar("apid", newword(npid, (word *)0));
		break;
	}
}
void Xsettrue(void){
	setstatus("");
}
void Xbang(void){
	setstatus(truestatus()?"false":"");
}
void Xclose(void){
	pushredir(RCLOSE, runq->code[runq->pc].i, 0);
	runq->pc++;
}
void Xdup(void){
	pushredir(RDUP, runq->code[runq->pc].i, runq->code[runq->pc+1].i);
	runq->pc+=2;
}
void Xeflag(void){
	if(eflagok && !truestatus()) Xexit();
}
void Xexit(void){
	struct var *trapreq;
	struct word *starval;
	static int beenhere=0;
	if(getpid()==mypid && !beenhere){
		trapreq=vlook("sigexit");
		if(trapreq->fn){
			beenhere=1;
			--runq->pc;
			starval=vlook("*")->val;
			start(trapreq->fn, trapreq->pc, (struct var *)0);
			runq->local=newvar(strdup("*"), runq->local);
			runq->local->val=copywords(starval, (struct word *)0);
			runq->local->changed=1;
			runq->redir=runq->startredir=0;
			return;
		}
	}
	Exit(getstatus());
}
void Xfalse(void){
	if(truestatus()) runq->pc=runq->code[runq->pc].i;
	else runq->pc++;
}
int ifnot;		/* dynamic if not flag */
void Xifnot(void){
	if(ifnot)
		runq->pc++;
	else
		runq->pc=runq->code[runq->pc].i;
}
void Xjump(void){
	runq->pc=runq->code[runq->pc].i;
}
void Xmark(void){
	pushlist();
}
void Xpopm(void){
	poplist();
}
void Xread(void){
	char *file;
	int f;
	switch(count(runq->argv->words)){
	default: Xerror1("< requires singleton\n"); return;
	case 0: Xerror1("< requires file\n"); return;
	case 1: break;
	}
	file=runq->argv->words->word;
	if((f=open(file, 0))<0){
		pfmt(err, "%s: ", file);
		Xerror("can't open");
		return;
	}
	pushredir(ROPEN, f, runq->code[runq->pc].i);
	runq->pc++;
	poplist();
}
void turfredir(void){
	while(runq->redir!=runq->startredir)
		Xpopredir();
}
void Xpopredir(void){
	struct redir *rp=runq->redir;
	if(rp==0) panic("turfredir null!", 0);
	runq->redir=rp->next;
	if(rp->type==ROPEN) close(rp->from);
	efree((char *)rp);
}
void Xreturn(void){
	struct thread *p=runq;
	turfredir();
	while(p->argv) poplist();
	codefree(p->code);
	runq=p->ret;
	efree((char *)p);
	if(runq==0) Exit(getstatus());
}
void Xtrue(void){
	if(truestatus()) runq->pc++;
	else runq->pc=runq->code[runq->pc].i;
}
void Xif(void){
	ifnot=1;
	if(truestatus()) runq->pc++;
	else runq->pc=runq->code[runq->pc].i;
}
void Xwastrue(void){
	ifnot=0;
}
void Xword(void){
	pushword(runq->code[runq->pc++].s);
}
void Xwrite(void){
	char *file;
	int f;
	switch(count(runq->argv->words)){
	default: Xerror1("> requires singleton\n"); return;
	case 0: Xerror1("> requires file\n"); return;
	case 1: break;
	}
	file=runq->argv->words->word;
	if((f=Creat(file))<0){
		pfmt(err, "%s: ", file);
		Xerror("can't open");
		return;
	}
	pushredir(ROPEN, f, runq->code[runq->pc].i);
	runq->pc++;
	poplist();
}
char *_list2str(word *words, int c){
	char *value, *s, *t;
	int len=0;
	word *ap;
	for(ap=words;ap;ap=ap->next)
		len+=1+strlen(ap->word);
	value=emalloc(len+1);
	s=value;
	for(ap=words;ap;ap=ap->next){
		for(t=ap->word;*t;) *s++=*t++;
		*s++=c;
	}
	if(s==value) *s='\0';
	else s[-1]='\0';
	return value;
}
char *list2str(word *words){
	return _list2str(words, ' ');
}
void Xmatch(void){
	word *p;
	char *subject;
	subject=list2str(runq->argv->words);
	setstatus("no match");
	for(p=runq->argv->next->words;p;p=p->next)
		if(match(subject, p->word, '\0')){
			setstatus("");
			break;
		}
	efree(subject);
	poplist();
	poplist();
}
void Xcase(void){
	word *p;
	char *s;
	int ok=0;
	s=list2str(runq->argv->next->words);
	for(p=runq->argv->words;p;p=p->next){
		if(match(s, p->word, '\0')){
			ok=1;
			break;
		}
	}
	efree(s);
	if(ok)
		runq->pc++;
	else
		runq->pc=runq->code[runq->pc].i;
	poplist();
}
word *conclist(word *lp, word *rp, word *tail)
{
	char *buf;
	word *v;
	if(lp->next || rp->next)
		tail=conclist(lp->next==0?lp:lp->next, rp->next==0?rp:rp->next,
			tail);
	buf=emalloc(strlen(lp->word)+strlen(rp->word)+1);
	strcpy(buf, lp->word);
	strcat(buf, rp->word);
	v=newword(buf, tail);
	efree(buf);
	return v;
}
void Xconc(void){
	word *lp=runq->argv->words;
	word *rp=runq->argv->next->words;
	word *vp=runq->argv->next->next->words;
	int lc=count(lp), rc=count(rp);
	if(lc!=0 || rc!=0){
		if(lc==0 || rc==0){
			Xerror1("null list in concatenation");
			return;
		}
		if(lc!=1 && rc!=1 && lc!=rc){
			Xerror1("mismatched list lengths in concatenation");
			return;
		}
		vp=conclist(lp, rp, vp);
	}
	poplist();
	poplist();
	runq->argv->words=vp;
}
void Xassign(void){
	var *v;
	if(count(runq->argv->words)!=1){
		Xerror1("variable name not singleton!");
		return;
	}
	deglob(runq->argv->words->word);
	v=vlook(runq->argv->words->word);
	poplist();
	globlist();
	freewords(v->val);
	v->val=runq->argv->words;
	v->changed=1;
	if(v->changefn)
		v->changefn(v);
	runq->argv->words=0;
	poplist();
}
/*
 * copy arglist a, adding the copy to the front of tail
 */
word *copywords(word *a, word *tail)
{
	word *v=0, **end;
	for(end=&v;a;a=a->next,end=&(*end)->next)
		*end=newword(a->word, 0);
	*end=tail;
	return v;
}
void Xdol(void){
	word *a, *star;
	char *s, *t;
	int n;
	if(count(runq->argv->words)!=1){
		Xerror1("variable name not singleton!");
		return;
	}
	s=runq->argv->words->word;
	deglob(s);
	n=0;
	for(t=s;'0'<=*t && *t<='9';t++) n=n*10+*t-'0';
	a=runq->argv->next->words;
	if(n==0 || *t)
		a=copywords(vlook(s)->val, a);
	else{
		star=vlook("*")->val;
		if(star && 1<=n && n<=count(star)){
			while(--n) star=star->next;
			a=newword(star->word, a);
		}
	}
	poplist();
	runq->argv->words=a;
}
void Xqdol(void){
	word *a, *p;
	char *s;
	int n;
	if(count(runq->argv->words)!=1){
		Xerror1("variable name not singleton!");
		return;
	}
	s=runq->argv->words->word;
	deglob(s);
	a=vlook(s)->val;
	poplist();
	n=count(a);
	if(n==0){
		pushword("");
		return;
	}
	for(p=a;p;p=p->next) n+=strlen(p->word);
	s=emalloc(n);
	if(a){
		strcpy(s, a->word);
		for(p=a->next;p;p=p->next){
			strcat(s, " ");
			strcat(s, p->word);
		}
	}
	else
		s[0]='\0';
	pushword(s);
	efree(s);
}
word *subwords(word *val, int len, word *sub, word *a)
{
	int n;
	char *s;
	if(!sub) return a;
	a=subwords(val, len, sub->next, a);
	s=sub->word;
	deglob(s);
	n=0;
	while('0'<=*s && *s<='9') n=n*10+ *s++ -'0';
	if(n<1 || len<n) return a;
	for(;n!=1;--n) val=val->next;
	return newword(val->word, a);
}
void Xsub(void){
	word *a, *v;
	char *s;
	if(count(runq->argv->next->words)!=1){
		Xerror1("variable name not singleton!");
		return;
	}
	s=runq->argv->next->words->word;
	deglob(s);
	a=runq->argv->next->next->words;
	v=vlook(s)->val;
	a=subwords(v, count(v), runq->argv->words, a);
	poplist();
	poplist();
	runq->argv->words=a;
}
void Xcount(void){
	word *a;
	char *s, *t;
	int n;
	char num[12];
	if(count(runq->argv->words)!=1){
		Xerror1("variable name not singleton!");
		return;
	}
	s=runq->argv->words->word;
	deglob(s);
	n=0;
	for(t=s;'0'<=*t && *t<='9';t++) n=n*10+*t-'0';
	if(n==0 || *t){
		a=vlook(s)->val;
		itoa(num, count(a));
	}
	else{
		a=vlook("*")->val;
		itoa(num, a && 1<=n && n<=count(a)?1:0);
	}
	poplist();
	pushword(num);
}
void Xlocal(void){
	if(count(runq->argv->words)!=1){
		Xerror1("variable name must be singleton\n");
		return;
	}
	deglob(runq->argv->words->word);
	runq->local=newvar(strdup(runq->argv->words->word), runq->local);
	runq->local->val=copywords(runq->argv->next->words, (word *)0);
	runq->local->changed=1;
	poplist();
	poplist();
}
void Xunlocal(void){
	var *v=runq->local, *hid;
	if(v==0) panic("Xunlocal: no locals!", 0);
	runq->local=v->next;
	hid=vlook(v->name);
	hid->changed=1;
	efree(v->name);
	freewords(v->val);
	efree((char *)v);
}
void freewords(word *w)
{
	word *nw;
	while(w){
		efree(w->word);
		nw=w->next;
		efree((char *)w);
		w=nw;
	}
}
void Xfn(void){
	var *v;
	word *a;
	int end;
	end=runq->code[runq->pc].i;
	for(a=runq->argv->words;a;a=a->next){
		v=gvlook(a->word);
		if(v->fn) codefree(v->fn);
		v->fn=codecopy(runq->code);
		v->pc=runq->pc+2;
		v->fnchanged=1;
	}
	runq->pc=end;
	poplist();
}
void Xdelfn(void){
	var *v;
	word *a;
	for(a=runq->argv->words;a;a=a->next){
		v=gvlook(a->word);
		if(v->fn) codefree(v->fn);
		v->fn=0;
		v->fnchanged=1;
	}
	poplist();
}
void Xpipe(void){
	struct thread *p=runq;
	int pc=p->pc, forkid;
	int lfd=p->code[pc++].i;
	int rfd=p->code[pc++].i;
	int pfd[2];
	if(pipe(pfd)<0){
		Xerror("can't get pipe");
		return;
	}
	switch(forkid=fork()){
	case -1:
		Xerror("try again");
		break;
	case 0:
		start(p->code, pc+2, runq->local);
		runq->ret=0;
		close(pfd[PRD]);
		pushredir(ROPEN, pfd[PWR], lfd);
		break;
	default:
		start(p->code, p->code[pc].i, runq->local);
		close(pfd[PWR]);
		pushredir(ROPEN, pfd[PRD], rfd);
		p->pc=p->code[pc+1].i;
		p->pid=forkid;
		break;
	}
}
char *concstatus(char *s, char *t)
{
	static char v[NSTATUS+1];
	int n=strlen(s);
	strncpy(v, s, NSTATUS);
	if(n<NSTATUS){
		v[n]='|';
		strncpy(v+n+1, t, NSTATUS-n-1);
	}
	v[NSTATUS]='\0';
	return v;
}
void Xpipewait(void){
	char status[NSTATUS+1];
	if(runq->pid==-1)
		setstatus(concstatus(runq->status, getstatus()));
	else{
		strncpy(status, getstatus(), NSTATUS);
		status[NSTATUS]='\0';
		Waitfor(runq->pid, 1);
		runq->pid=-1;
		setstatus(concstatus(getstatus(), status));
	}
}
void Xrdcmds(void){
	struct thread *p=runq;
	word *prompt;
	flush(err);
	nerror=0;
	if(flag['s'] && !truestatus())
		pfmt(err, "status=%v\n", vlook("status")->val);
	if(runq->iflag){
		prompt=vlook("prompt")->val;
		if(prompt)
			promptstr=prompt->word;
		else
			promptstr="% ";
	}
	Noerror();
	if(yyparse()){
		if(!p->iflag || p->eof && !Eintr()){
			if(p->cmdfile) efree(p->cmdfile);
			closeio(p->cmdfd);
			Xreturn();	/* should this be omitted? */
		}
		else{
			if(Eintr()){
				pchr(err, '\n');
				p->eof=0;
			}
			--p->pc;	/* go back for next command */
		}
	}
	else{
		ntrap = 0;	/* avoid double-interrupts during blocked writes */
		--p->pc;	/* re-execute Xrdcmds after codebuf runs */
		start(codebuf, 1, runq->local);
	}
	freenodes();
}
void Xerror(char *s)
{
	if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0)
		pfmt(err, "rc: %s: %r\n", s);
	else
		pfmt(err, "rc (%s): %s: %r\n", argv0, s);
	flush(err);
	setstatus("error");
	while(!runq->iflag) Xreturn();
}
void Xerror1(char *s)
{
	if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0)
		pfmt(err, "rc: %s\n", s);
	else
		pfmt(err, "rc (%s): %s\n", argv0, s);
	flush(err);
	setstatus("error");
	while(!runq->iflag) Xreturn();
}
void Xbackq(void){
	char wd[8193];
	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;
	}
	switch(pid=fork()){
	case -1: Xerror("try again");
		close(pfd[PRD]);
		close(pfd[PWR]);
		return;
	case 0:
		close(pfd[PRD]);
		start(runq->code, runq->pc+1, runq->local);
		pushredir(ROPEN, pfd[PWR], 1);
		return;
	default:
		close(pfd[PWR]);
		f=openfd(pfd[PRD]);
		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, 0);
		/* 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=runq->code[runq->pc].i;
		return;
	}
}
/*
 * Who should wait for the exit from the fork?
 */
void Xpipefd(void){
	struct thread *p=runq;
	int pc=p->pc;
	char name[40];
	int pfd[2];
	int sidefd, mainfd;
	if(pipe(pfd)<0){
		Xerror("can't get pipe");
		return;
	}
	if(p->code[pc].i==READ){
		sidefd=pfd[PWR];
		mainfd=pfd[PRD];
	}
	else{
		sidefd=pfd[PRD];
		mainfd=pfd[PWR];
	}
	switch(fork()){
	case -1:
		Xerror("try again");
		break;
	case 0:
		start(p->code, pc+2, runq->local);
		close(mainfd);
		pushredir(ROPEN, sidefd, p->code[pc].i==READ?1:0);
		runq->ret=0;
		break;
	default:
		close(sidefd);
		pushredir(ROPEN, mainfd, mainfd);	/* isn't this a noop? */
		strcpy(name, Fdprefix);
		itoa(name+strlen(name), mainfd);
		pushword(name);
		p->pc=p->code[pc+1].i;
		break;
	}
}
void Xsubshell(void){
	int pid;
	switch(pid=fork()){
	case -1:
		Xerror("try again");
		break;
	case 0:
		start(runq->code, runq->pc+1, runq->local);
		runq->ret=0;
		break;
	default:
		Waitfor(pid, 1);
		runq->pc=runq->code[runq->pc].i;
		break;
	}
}
void setstatus(char *s)
{
	setvar("status", newword(s, (word *)0));
}
char *getstatus(void){
	var *status=vlook("status");
	return status->val?status->val->word:"";
}
int truestatus(void){
	char *s;
	for(s=getstatus();*s;s++)
		if(*s!='|' && *s!='0') return 0;
	return 1;
}
void Xdelhere(void){
	Unlink(runq->code[runq->pc++].s);
}
void Xfor(void){
	if(runq->argv->words==0){
		poplist();
		runq->pc=runq->code[runq->pc].i;
	}
	else{
		freelist(runq->local->val);
		runq->local->val=runq->argv->words;
		runq->local->changed=1;
		runq->argv->words=runq->argv->words->next;
		runq->local->val->next=0;
		runq->pc++;
	}
}
void Xglob(void){
	globlist();
}
