#include <u.h>
#include <signal.h>
#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;

	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);
	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);
	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();
}
