Index: /trunk/src/ash-messup/Makefile.kmk
===================================================================
--- /trunk/src/ash-messup/Makefile.kmk	(revision 883)
+++ /trunk/src/ash-messup/Makefile.kmk	(revision 884)
@@ -30,4 +30,5 @@
 kmk_ash_INCS.win = win
 kmk_ash_SOURCES = \
+	main.c \
 	alias.c \
 	cd.c \
@@ -40,5 +41,4 @@
 	jobs.c \
 	mail.c \
-	main.c \
 	memalloc.c \
 	miscbltin.c \
Index: /trunk/src/ash-messup/eval.c
===================================================================
--- /trunk/src/ash-messup/eval.c	(revision 883)
+++ /trunk/src/ash-messup/eval.c	(revision 884)
@@ -87,4 +87,5 @@
 #include "myhistedit.h"
 #endif
+#include "shinstance.h"
 
 
@@ -94,24 +95,24 @@
 #define EV_BACKCMD 04		/* command executing within back quotes */
 
-int evalskip;			/* set if we are skipping commands */
-STATIC int skipcount;		/* number of levels to skip */
-MKINIT int loopnest;		/* current loop nesting level */
-int funcnest;			/* depth of function calls */
+/*int evalskip;*/			/* set if we are skipping commands */
+/*STATIC int skipcount;*/		/* number of levels to skip */
+/*MKINIT int loopnest;*/		/* current loop nesting level */
+/*int funcnest;*/			/* depth of function calls */
 
 
 /*char *commandname;*/
-struct strlist *cmdenviron;
-int exitstatus;			/* exit status of last command */
-int back_exitstatus;		/* exit status of backquoted command */
-
-
-STATIC void evalloop(union node *, int);
-STATIC void evalfor(union node *, int);
-STATIC void evalcase(union node *, int);
-STATIC void evalsubshell(union node *, int);
-STATIC void expredir(union node *);
-STATIC void evalpipe(union node *);
-STATIC void evalcommand(union node *, int, struct backcmd *);
-STATIC void prehash(union node *);
+/*struct strlist *cmdenviron;*/
+/*int exitstatus;*/			/* exit status of last command */
+/*int back_exitstatus;*/		/* exit status of backquoted command */
+
+
+STATIC void evalloop(shinstance *, union node *, int);
+STATIC void evalfor(shinstance *, union node *, int);
+STATIC void evalcase(shinstance *, union node *, int);
+STATIC void evalsubshell(shinstance *, union node *, int);
+STATIC void expredir(shinstance *, union node *);
+STATIC void evalpipe(shinstance *, union node *);
+STATIC void evalcommand(shinstance *, union node *, int, struct backcmd *);
+STATIC void prehash(shinstance *, union node *);
 
 
@@ -135,15 +136,15 @@
 
 static int
-sh_pipe(int fds[2])
+sh_pipe(shinstance *psh, int fds[2])
 {
 	int nfd;
 
-	if (pipe(fds))
+	if (shfile_pipe(&psh->fdtab, fds))
 		return -1;
 
 	if (fds[0] < 3) {
-		nfd = fcntl(fds[0], F_DUPFD, 3);
+		nfd = shfile_fcntl(&psh->fdtab, fds[0], F_DUPFD, 3);
 		if (nfd != -1) {
-			close(fds[0]);
+			shfile_close(&psh->fdtab, fds[0]);
 			fds[0] = nfd;
 		}
@@ -151,7 +152,7 @@
 
 	if (fds[1] < 3) {
-		nfd = fcntl(fds[1], F_DUPFD, 3);
+		nfd = shfile_fcntl(&psh->fdtab, fds[1], F_DUPFD, 3);
 		if (nfd != -1) {
-			close(fds[1]);
+			shfile_close(&psh->fdtab, fds[1]);
 			fds[1] = nfd;
 		}
@@ -166,5 +167,5 @@
 
 int
-evalcmd(int argc, char **argv)
+evalcmd(shinstance *psh, int argc, char **argv)
 {
         char *p;
@@ -187,7 +188,7 @@
                         p = grabstackstr(concat);
                 }
-                evalstring(p, EV_TESTED);
+                evalstring(psh, p, EV_TESTED);
         }
-        return exitstatus;
+        return psh->exitstatus;
 }
 
@@ -198,18 +199,18 @@
 
 void
-evalstring(char *s, int flag)
+evalstring(shinstance *psh, char *s, int flag)
 {
 	union node *n;
 	struct stackmark smark;
 
-	setstackmark(&smark);
-	setinputstring(s, 1);
-
-	while ((n = parsecmd(0)) != NEOF) {
-		evaltree(n, flag);
-		popstackmark(&smark);
-	}
-	popfile();
-	popstackmark(&smark);
+	setstackmark(psh, &smark);
+	setinputstring(psh, s, 1);
+
+	while ((n = parsecmd(psh, 0)) != NEOF) {
+		evaltree(psh, n, flag);
+		popstackmark(psh, &smark);
+	}
+	popfile(psh);
+	popstackmark(psh, &smark);
 }
 
@@ -222,13 +223,13 @@
 
 void
-evaltree(union node *n, int flags)
+evaltree(shinstance *psh, union node *n, int flags)
 {
 	if (n == NULL) {
 		TRACE(("evaltree(NULL) called\n"));
-		exitstatus = 0;
+		psh->exitstatus = 0;
 		goto out;
 	}
 #ifndef SMALL
-	displayhist = 1;	/* show history substitutions done with fc */
+	psh->displayhist = 1;	/* show history substitutions done with fc */
 #endif
 	TRACE(("pid %d, evaltree(%p: %d, %d) called\n",
@@ -236,114 +237,114 @@
 	switch (n->type) {
 	case NSEMI:
-		evaltree(n->nbinary.ch1, flags & EV_TESTED);
-		if (evalskip)
+		evaltree(psh, n->nbinary.ch1, flags & EV_TESTED);
+		if (psh->evalskip)
 			goto out;
-		evaltree(n->nbinary.ch2, flags);
+		evaltree(psh, n->nbinary.ch2, flags);
 		break;
 	case NAND:
-		evaltree(n->nbinary.ch1, EV_TESTED);
-		if (evalskip || exitstatus != 0)
+		evaltree(psh, n->nbinary.ch1, EV_TESTED);
+		if (psh->evalskip || psh->exitstatus != 0)
 			goto out;
-		evaltree(n->nbinary.ch2, flags);
+		evaltree(psh, n->nbinary.ch2, flags);
 		break;
 	case NOR:
-		evaltree(n->nbinary.ch1, EV_TESTED);
-		if (evalskip || exitstatus == 0)
+		evaltree(psh, n->nbinary.ch1, EV_TESTED);
+		if (psh->evalskip || psh->exitstatus == 0)
 			goto out;
-		evaltree(n->nbinary.ch2, flags);
+		evaltree(psh, n->nbinary.ch2, flags);
 		break;
 	case NREDIR:
-		expredir(n->nredir.redirect);
-		redirect(n->nredir.redirect, REDIR_PUSH);
-		evaltree(n->nredir.n, flags);
-		popredir();
+		expredir(psh, n->nredir.redirect);
+		redirect(psh, n->nredir.redirect, REDIR_PUSH);
+		evaltree(psh, n->nredir.n, flags);
+		popredir(psh);
 		break;
 	case NSUBSHELL:
-		evalsubshell(n, flags);
+		evalsubshell(psh, n, flags);
 		break;
 	case NBACKGND:
-		evalsubshell(n, flags);
+		evalsubshell(psh, n, flags);
 		break;
 	case NIF: {
-		evaltree(n->nif.test, EV_TESTED);
-		if (evalskip)
+		evaltree(psh, n->nif.test, EV_TESTED);
+		if (psh->evalskip)
 			goto out;
-		if (exitstatus == 0)
-			evaltree(n->nif.ifpart, flags);
+		if (psh->exitstatus == 0)
+			evaltree(psh, n->nif.ifpart, flags);
 		else if (n->nif.elsepart)
-			evaltree(n->nif.elsepart, flags);
+			evaltree(psh, n->nif.elsepart, flags);
 		else
-			exitstatus = 0;
+			psh->exitstatus = 0;
 		break;
 	}
 	case NWHILE:
 	case NUNTIL:
-		evalloop(n, flags);
+		evalloop(psh, n, flags);
 		break;
 	case NFOR:
-		evalfor(n, flags);
+		evalfor(psh, n, flags);
 		break;
 	case NCASE:
-		evalcase(n, flags);
+		evalcase(psh, n, flags);
 		break;
 	case NDEFUN:
-		defun(n->narg.text, n->narg.next);
-		exitstatus = 0;
+		defun(psh, n->narg.text, n->narg.next);
+		psh->exitstatus = 0;
 		break;
 	case NNOT:
-		evaltree(n->nnot.com, EV_TESTED);
-		exitstatus = !exitstatus;
+		evaltree(psh, n->nnot.com, EV_TESTED);
+		psh->exitstatus = !psh->exitstatus;
 		break;
 	case NPIPE:
-		evalpipe(n);
+		evalpipe(psh, n);
 		break;
 	case NCMD:
-		evalcommand(n, flags, (struct backcmd *)NULL);
+		evalcommand(psh, n, flags, (struct backcmd *)NULL);
 		break;
 	default:
-		out1fmt("Node type = %d\n", n->type);
-		flushout(&output);
+		out1fmt(psh, "Node type = %d\n", n->type);
+		flushout(&psh->output);
 		break;
 	}
 out:
-	if (pendingsigs)
-		dotrap();
+	if (psh->pendingsigs)
+		dotrap(psh);
 	if ((flags & EV_EXIT) != 0)
-		exitshell(exitstatus);
+		exitshell(psh, psh->exitstatus);
 }
 
 
 STATIC void
-evalloop(union node *n, int flags)
+evalloop(shinstance *psh, union node *n, int flags)
 {
 	int status;
 
-	loopnest++;
+	psh->loopnest++;
 	status = 0;
 	for (;;) {
-		evaltree(n->nbinary.ch1, EV_TESTED);
-		if (evalskip) {
-skipping:	  if (evalskip == SKIPCONT && --skipcount <= 0) {
-				evalskip = 0;
+		evaltree(psh, n->nbinary.ch1, EV_TESTED);
+		if (psh->evalskip) {
+skipping:	  if (psh->evalskip == SKIPCONT && --psh->skipcount <= 0) {
+				psh->evalskip = 0;
 				continue;
 			}
-			if (evalskip == SKIPBREAK && --skipcount <= 0)
-				evalskip = 0;
+			if (psh->evalskip == SKIPBREAK && --psh->skipcount <= 0)
+				psh->evalskip = 0;
 			break;
 		}
 		if (n->type == NWHILE) {
-			if (exitstatus != 0)
+			if (psh->exitstatus != 0)
 				break;
 		} else {
-			if (exitstatus == 0)
+			if (psh->exitstatus == 0)
 				break;
 		}
-		evaltree(n->nbinary.ch2, flags & EV_TESTED);
-		status = exitstatus;
-		if (evalskip)
+		evaltree(psh, n->nbinary.ch2, flags & EV_TESTED);
+		status = psh->exitstatus;
+		if (psh->evalskip)
 			goto skipping;
 	}
-	loopnest--;
-	exitstatus = status;
+	psh->loopnest--;
+	psh->exitstatus = status;
 }
 
@@ -351,5 +352,5 @@
 
 STATIC void
-evalfor(union node *n, int flags)
+evalfor(shinstance *psh, union node *n, int flags)
 {
 	struct arglist arglist;
@@ -359,32 +360,32 @@
 	int status = 0;
 
-	setstackmark(&smark);
+	setstackmark(psh, &smark);
 	arglist.lastp = &arglist.list;
 	for (argp = n->nfor.args ; argp ; argp = argp->narg.next) {
-		expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
-		if (evalskip)
+		expandarg(psh, argp, &arglist, EXP_FULL | EXP_TILDE);
+		if (psh->evalskip)
 			goto out;
 	}
 	*arglist.lastp = NULL;
 
-	loopnest++;
+	psh->loopnest++;
 	for (sp = arglist.list ; sp ; sp = sp->next) {
-		setvar(n->nfor.var, sp->text, 0);
-		evaltree(n->nfor.body, flags & EV_TESTED);
-		status = exitstatus;
-		if (evalskip) {
-			if (evalskip == SKIPCONT && --skipcount <= 0) {
-				evalskip = 0;
+		setvar(psh, n->nfor.var, sp->text, 0);
+		evaltree(psh, n->nfor.body, flags & EV_TESTED);
+		status = psh->exitstatus;
+		if (psh->evalskip) {
+			if (psh->evalskip == SKIPCONT && --psh->skipcount <= 0) {
+				psh->evalskip = 0;
 				continue;
 			}
-			if (evalskip == SKIPBREAK && --skipcount <= 0)
-				evalskip = 0;
+			if (psh->evalskip == SKIPBREAK && --psh->skipcount <= 0)
+				psh->evalskip = 0;
 			break;
 		}
 	}
-	loopnest--;
-	exitstatus = status;
+	psh->loopnest--;
+	psh->exitstatus = status;
 out:
-	popstackmark(&smark);
+	popstackmark(psh, &smark);
 }
 
@@ -392,5 +393,5 @@
 
 STATIC void
-evalcase(union node *n, int flags)
+evalcase(shinstance *psh, union node *n, int flags)
 {
 	union node *cp;
@@ -400,13 +401,13 @@
 	int status = 0;
 
-	setstackmark(&smark);
+	setstackmark(psh, &smark);
 	arglist.lastp = &arglist.list;
-	expandarg(n->ncase.expr, &arglist, EXP_TILDE);
-	for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) {
+	expandarg(psh, n->ncase.expr, &arglist, EXP_TILDE);
+	for (cp = n->ncase.cases ; cp && psh->evalskip == 0 ; cp = cp->nclist.next) {
 		for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
-			if (casematch(patp, arglist.list->text)) {
-				if (evalskip == 0) {
-					evaltree(cp->nclist.body, flags);
-					status = exitstatus;
+			if (casematch(psh, patp, arglist.list->text)) {
+				if (psh->evalskip == 0) {
+					evaltree(psh, cp->nclist.body, flags);
+					status = psh->exitstatus;
 				}
 				goto out;
@@ -415,6 +416,6 @@
 	}
 out:
-	exitstatus = status;
-	popstackmark(&smark);
+	psh->exitstatus = status;
+	popstackmark(psh, &smark);
 }
 
@@ -426,22 +427,22 @@
 
 STATIC void
-evalsubshell(union node *n, int flags)
+evalsubshell(shinstance *psh, union node *n, int flags)
 {
 	struct job *jp;
 	int backgnd = (n->type == NBACKGND);
 
-	expredir(n->nredir.redirect);
+	expredir(psh, n->nredir.redirect);
 	INTOFF;
-	jp = makejob(n, 1);
-	if (forkshell(jp, n, backgnd ? FORK_BG : FORK_FG) == 0) {
+	jp = makejob(psh, n, 1);
+	if (forkshell(psh, jp, n, backgnd ? FORK_BG : FORK_FG) == 0) {
 		INTON;
 		if (backgnd)
 			flags &=~ EV_TESTED;
-		redirect(n->nredir.redirect, 0);
+		redirect(psh, n->nredir.redirect, 0);
 		/* never returns */
-		evaltree(n->nredir.n, flags | EV_EXIT);
+		evaltree(psh, n->nredir.n, flags | EV_EXIT);
 	}
 	if (! backgnd)
-		exitstatus = waitforjob(jp);
+		psh->exitstatus = waitforjob(psh, jp);
 	INTON;
 }
@@ -454,5 +455,5 @@
 
 STATIC void
-expredir(union node *n)
+expredir(shinstance *psh, union node *n)
 {
 	union node *redir;
@@ -467,5 +468,5 @@
 		case NCLOBBER:
 		case NAPPEND:
-			expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
+			expandarg(psh, redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
 			redir->nfile.expfname = fn.list->text;
 			break;
@@ -473,6 +474,6 @@
 		case NTOFD:
 			if (redir->ndup.vname) {
-				expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE);
-				fixredir(redir, fn.list->text, 1);
+				expandarg(psh, redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE);
+				fixredir(psh, redir, fn.list->text, 1);
 			}
 			break;
@@ -491,5 +492,5 @@
 
 STATIC void
-evalpipe(union node *n)
+evalpipe(shinstance *psh, union node *n)
 {
 	struct job *jp;
@@ -504,40 +505,40 @@
 		pipelen++;
 	INTOFF;
-	jp = makejob(n, pipelen);
+	jp = makejob(psh, n, pipelen);
 	prevfd = -1;
 	for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
-		prehash(lp->n);
+		prehash(psh, lp->n);
 		pip[1] = -1;
 		if (lp->next) {
-			if (sh_pipe(pip) < 0) {
-				close(prevfd);
-				error("Pipe call failed");
-			}
-		}
-		if (forkshell(jp, lp->n, n->npipe.backgnd ? FORK_BG : FORK_FG) == 0) {
+			if (sh_pipe(psh, pip) < 0) {
+				shfile_close(&psh->fdtab, prevfd);
+				error(psh, "Pipe call failed");
+			}
+		}
+		if (forkshell(psh, jp, lp->n, n->npipe.backgnd ? FORK_BG : FORK_FG) == 0) {
 			INTON;
 			if (prevfd > 0) {
-				close(0);
-				copyfd(prevfd, 0);
-				close(prevfd);
+				shfile_close(&psh->fdtab, 0);
+				copyfd(psh, prevfd, 0);
+				shfile_close(&psh->fdtab, prevfd);
 			}
 			if (pip[1] >= 0) {
-				close(pip[0]);
+				shfile_close(&psh->fdtab, pip[0]);
 				if (pip[1] != 1) {
-					close(1);
-					copyfd(pip[1], 1);
-					close(pip[1]);
+					shfile_close(&psh->fdtab, 1);
+					copyfd(psh, pip[1], 1);
+					shfile_close(&psh->fdtab, pip[1]);
 				}
 			}
-			evaltree(lp->n, EV_EXIT);
+			evaltree(psh, lp->n, EV_EXIT);
 		}
 		if (prevfd >= 0)
-			close(prevfd);
+			shfile_close(&psh->fdtab, prevfd);
 		prevfd = pip[0];
-		close(pip[1]);
+		shfile_close(&psh->fdtab, pip[1]);
 	}
 	if (n->npipe.backgnd == 0) {
-		exitstatus = waitforjob(jp);
-		TRACE(("evalpipe:  job done exit status %d\n", exitstatus));
+		psh->exitstatus = waitforjob(psh, jp);
+		TRACE(("evalpipe:  job done exit status %d\n", psh->exitstatus));
 	}
 	INTON;
@@ -554,5 +555,5 @@
 
 void
-evalbackcmd(union node *n, struct backcmd *result)
+evalbackcmd(shinstance *psh, union node *n, struct backcmd *result)
 {
 	int pip[2];
@@ -560,5 +561,5 @@
 	struct stackmark smark;		/* unnecessary */
 
-	setstackmark(&smark);
+	setstackmark(psh, &smark);
 	result->fd = -1;
 	result->buf = NULL;
@@ -576,26 +577,26 @@
 	 */
 	if (n->type == NCMD) {
-		exitstatus = oexitstatus;
-		evalcommand(n, EV_BACKCMD, result);
+		psh->exitstatus = opsh->exitstatus;
+		evalcommand(psh, n, EV_BACKCMD, result);
 	} else
 #endif
 	{
 		INTOFF;
-		if (sh_pipe(pip) < 0)
-			error("Pipe call failed");
-		jp = makejob(n, 1);
-		if (forkshell(jp, n, FORK_NOJOB) == 0) {
+		if (sh_pipe(psh, pip) < 0)
+			error(psh, "Pipe call failed");
+		jp = makejob(psh, n, 1);
+		if (forkshell(psh, jp, n, FORK_NOJOB) == 0) {
 			FORCEINTON;
-			close(pip[0]);
+			shfile_close(&psh->fdtab, pip[0]);
 			if (pip[1] != 1) {
-				close(1);
-				copyfd(pip[1], 1);
-				close(pip[1]);
-			}
-			eflag = 0;
-			evaltree(n, EV_EXIT);
+				shfile_close(&psh->fdtab, 1);
+				copyfd(psh, pip[1], 1);
+				shfile_close(&psh->fdtab, pip[1]);
+			}
+			psh->eflag = 0;
+			evaltree(psh, n, EV_EXIT);
 			/* NOTREACHED */
 		}
-		close(pip[1]);
+		shfile_close(&psh->fdtab, pip[1]);
 		result->fd = pip[0];
 		result->jp = jp;
@@ -603,5 +604,5 @@
 	}
 out:
-	popstackmark(&smark);
+	popstackmark(psh, &smark);
 	TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
 		result->fd, result->buf, result->nleft, result->jp));
@@ -609,5 +610,5 @@
 
 static const char *
-syspath(void)
+syspath(shinstance *psh)
 {
 #ifdef CTL_USER
@@ -641,5 +642,5 @@
 
 static int
-parse_command_args(int argc, char **argv, int *use_syspath)
+parse_command_args(shinstance *psh, int argc, char **argv, int *use_syspath)
 {
 	int sv_argc = argc;
@@ -674,5 +675,5 @@
 }
 
-int vforked = 0;
+/*int vforked = 0;*/
 
 /*
@@ -681,5 +682,5 @@
 
 STATIC void
-evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
+evalcommand(shinstance *psh, union node *cmd, int flags, struct backcmd *backcmd)
 {
 	struct stackmark smark;
@@ -703,5 +704,5 @@
 	volatile int e;
 	char *lastarg;
-	const char *path = pathval();
+	const char *path = pathval(psh);
 	volatile int temp_path;
 #if __GNUC__
@@ -713,9 +714,9 @@
 #endif
 
-	vforked = 0;
+	psh->vforked = 0;
 	/* First expand the arguments. */
 	TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
-	setstackmark(&smark);
-	back_exitstatus = 0;
+	setstackmark(psh, &smark);
+	psh->exitstatus = 0;
 
 	arglist.lastp = &arglist.list;
@@ -731,10 +732,10 @@
 				continue;
 		}
-		expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
+		expandarg(psh, argp, &arglist, EXP_FULL | EXP_TILDE);
 		varflag = 0;
 	}
 	*arglist.lastp = NULL;
 
-	expredir(cmd->ncmd.redirect);
+	expredir(psh, cmd->ncmd.redirect);
 
 	/* Now do the initial 'name=value' ones we skipped above */
@@ -749,5 +750,5 @@
 		if (*p != '=')
 			break;
-		expandarg(argp, &varlist, EXP_VARTILDE);
+		expandarg(psh, argp, &varlist, EXP_VARTILDE);
 	}
 	*varlist.lastp = NULL;
@@ -756,5 +757,5 @@
 	for (sp = arglist.list ; sp ; sp = sp->next)
 		argc++;
-	argv = stalloc(sizeof (char *) * (argc + 1));
+	argv = stalloc(psh, sizeof (char *) * (argc + 1));
 
 	for (sp = arglist.list ; sp ; sp = sp->next) {
@@ -764,26 +765,26 @@
 	*argv = NULL;
 	lastarg = NULL;
-	if (iflag && funcnest == 0 && argc > 0)
+	if (psh->iflag && psh->funcnest == 0 && argc > 0)
 		lastarg = argv[-1];
 	argv -= argc;
 
 	/* Print the command if xflag is set. */
-	if (xflag) {
+	if (psh->xflag) {
 		char sep = 0;
-		out2str(ps4val());
+		out2str(psh, ps4val(psh));
 		for (sp = varlist.list ; sp ; sp = sp->next) {
 			if (sep != 0)
-				outc(sep, &errout);
-			out2str(sp->text);
+				outc(sep, &psh->errout);
+			out2str(psh, sp->text);
 			sep = ' ';
 		}
 		for (sp = arglist.list ; sp ; sp = sp->next) {
 			if (sep != 0)
-				outc(sep, &errout);
-			out2str(sp->text);
+				outc(sep, &psh->errout);
+			out2str(psh, sp->text);
 			sep = ' ';
 		}
-		outc('\n', &errout);
-		flushout(&errout);
+		outc('\n', &psh->errout);
+		flushout(&psh->errout);
 	}
 
@@ -806,8 +807,8 @@
 		do {
 			int argsused, use_syspath;
-			find_command(argv[0], &cmdentry, cmd_flags, path);
+			find_command(psh, argv[0], &cmdentry, cmd_flags, path);
 			if (cmdentry.cmdtype == CMDUNKNOWN) {
-				exitstatus = 127;
-				flushout(&errout);
+				psh->exitstatus = 127;
+				flushout(&psh->errout);
 				goto out;
 			}
@@ -818,5 +819,5 @@
 				break;
 			cmd_flags |= DO_NOFUNC;
-			argsused = parse_command_args(argc, argv, &use_syspath);
+			argsused = parse_command_args(psh, argc, argv, &use_syspath);
 			if (argsused == 0) {
 				/* use 'type' builting to display info */
@@ -827,5 +828,5 @@
 			argv += argsused;
 			if (use_syspath)
-				path = syspath() + 5;
+				path = syspath(psh) + 5;
 		} while (argc != 0);
 		if (cmdentry.cmdtype == CMDSPLBLTIN && cmd_flags & DO_NOFUNC)
@@ -843,10 +844,10 @@
 		 || cmdentry.u.bltin == evalcmd))) {
 		INTOFF;
-		jp = makejob(cmd, 1);
+		jp = makejob(psh, cmd, 1);
 		mode = cmd->ncmd.backgnd;
 		if (flags & EV_BACKCMD) {
 			mode = FORK_NOJOB;
-			if (sh_pipe(pip) < 0)
-				error("Pipe call failed");
+			if (sh_pipe(psh, pip) < 0)
+				error(psh, "Pipe call failed");
 		}
 #ifdef DO_SHAREDVFORK
@@ -858,12 +859,12 @@
 			pid_t	pid;
 
-			savelocalvars = localvars;
-			localvars = NULL;
-			vforked = 1;
+			savelocalvars = psh->localvars;
+			psh->localvars = NULL;
+			psh->vforked = 1;
 			switch (pid = vfork()) {
 			case -1:
 				TRACE(("Vfork failed, errno=%d\n", errno));
 				INTON;
-				error("Cannot vfork");
+				error(psh, "Cannot vfork");
 				break;
 			case 0:
@@ -872,33 +873,33 @@
 				 */
 				if (setjmp(jmploc.loc)) {
-					if (exception == EXSHELLPROC) {
+					if (psh->exception == EXSHELLPROC) {
 						/* We can't progress with the vfork,
 						 * so, set vforked = 2 so the parent
 						 * knows, and _exit();
 						 */
-						vforked = 2;
-						_exit(0);
+						psh->vforked = 2;
+						sh__exit(psh, 0);
 					} else {
-						_exit(exerrno);
+						sh__exit(psh, exerrno);
 					}
 				}
-				savehandler = handler;
-				handler = &jmploc;
-				listmklocal(varlist.list, VEXPORT | VNOFUNC);
-				forkchild(jp, cmd, mode, vforked);
+				savehandler = psh->handler;
+				psh->handler = &jmploc;
+				listmklocal(psh, varlist.list, VEXPORT | VNOFUNC);
+				forkchild(psh, jp, cmd, mode, psh->vforked);
 				break;
 			default:
-				handler = savehandler;	/* restore from vfork(2) */
-				poplocalvars();
-				localvars = savelocalvars;
-				if (vforked == 2) {
-					vforked = 0;
-
-					(void)waitpid(pid, NULL, 0);
+				psh->handler = savehandler;	/* restore from vfork(2) */
+				poplocalvars(psh);
+				psh->localvars = savelocalvars;
+				if (psh->vforked == 2) {
+					psh->vforked = 0;
+
+					(void)sh_waitpid(psh, pid, NULL, 0);
 					/* We need to progress in a normal fork fashion */
 					goto normal_fork;
 				}
-				vforked = 0;
-				forkparent(jp, cmd, mode, pid);
+				psh->vforked = 0;
+				forkparent(psh, jp, cmd, mode, pid);
 				goto parent;
 			}
@@ -906,5 +907,5 @@
 normal_fork:
 #endif
-			if (forkshell(jp, cmd, mode) != 0)
+			if (forkshell(psh, jp, cmd, mode) != 0)
 				goto parent;	/* at end of routine */
 			FORCEINTON;
@@ -913,12 +914,12 @@
 #endif
 		if (flags & EV_BACKCMD) {
-			if (!vforked) {
+			if (!psh->vforked) {
 				FORCEINTON;
 			}
-			close(pip[0]);
+			shfile_close(&psh->fdtab, pip[0]);
 			if (pip[1] != 1) {
-				close(1);
-				copyfd(pip[1], 1);
-				close(pip[1]);
+				shfile_close(&psh->fdtab, 1);
+				copyfd(psh, pip[1], 1);
+				shfile_close(&psh->fdtab, pip[1]);
 			}
 		}
@@ -933,50 +934,50 @@
 		trputs("Shell function:  ");  trargs(argv);
 #endif
-		redirect(cmd->ncmd.redirect, REDIR_PUSH);
-		saveparam = shellparam;
-		shellparam.malloc = 0;
-		shellparam.reset = 1;
-		shellparam.nparam = argc - 1;
-		shellparam.p = argv + 1;
-		shellparam.optnext = NULL;
+		redirect(psh, cmd->ncmd.redirect, REDIR_PUSH);
+		saveparam = psh->shellparam;
+		psh->shellparam.malloc = 0;
+		psh->shellparam.reset = 1;
+		psh->shellparam.nparam = argc - 1;
+		psh->shellparam.p = argv + 1;
+		psh->shellparam.optnext = NULL;
 		INTOFF;
-		savelocalvars = localvars;
-		localvars = NULL;
+		savelocalvars = psh->localvars;
+		psh->localvars = NULL;
 		INTON;
 		if (setjmp(jmploc.loc)) {
-			if (exception == EXSHELLPROC) {
+			if (psh->exception == EXSHELLPROC) {
 				freeparam((volatile struct shparam *)
 				    &saveparam);
 			} else {
-				freeparam(&shellparam);
-				shellparam = saveparam;
-			}
-			poplocalvars();
-			localvars = savelocalvars;
-			handler = savehandler;
-			longjmp(handler->loc, 1);
-		}
-		savehandler = handler;
-		handler = &jmploc;
-		listmklocal(varlist.list, 0);
+				freeparam(&psh->shellparam);
+				psh->shellparam = saveparam;
+			}
+			poplocalvars(psh);
+			psh->localvars = savelocalvars;
+			psh->handler = savehandler;
+			longjmp(psh->handler->loc, 1);
+		}
+		savehandler = psh->handler;
+		psh->handler = &jmploc;
+		listmklocal(psh, varlist.list, 0);
 		/* stop shell blowing its stack */
-		if (++funcnest > 1000)
-			error("too many nested function calls");
-		evaltree(cmdentry.u.func, flags & EV_TESTED);
-		funcnest--;
+		if (++psh->funcnest > 1000)
+			error(psh, "too many nested function calls");
+		evaltree(psh, cmdentry.u.func, flags & EV_TESTED);
+		psh->funcnest--;
 		INTOFF;
-		poplocalvars();
-		localvars = savelocalvars;
-		freeparam(&shellparam);
-		shellparam = saveparam;
-		handler = savehandler;
-		popredir();
+		poplocalvars(psh);
+		psh->localvars = savelocalvars;
+		freeparam(&psh->shellparam);
+		psh->shellparam = saveparam;
+		psh->handler = savehandler;
+		popredir(psh);
 		INTON;
-		if (evalskip == SKIPFUNC) {
-			evalskip = 0;
-			skipcount = 0;
+		if (psh->evalskip == SKIPFUNC) {
+			psh->evalskip = 0;
+			psh->skipcount = 0;
 		}
 		if (flags & EV_EXIT)
-			exitshell(exitstatus);
+			exitshell(psh, psh->exitstatus);
 		break;
 
@@ -988,13 +989,13 @@
 		mode = (cmdentry.u.bltin == execcmd) ? 0 : REDIR_PUSH;
 		if (flags == EV_BACKCMD) {
-			memout.nleft = 0;
-			memout.nextc = memout.buf;
-			memout.bufsize = 64;
+			psh->memout.nleft = 0;
+			psh->memout.nextc = psh->memout.buf;
+			psh->memout.bufsize = 64;
 			mode |= REDIR_BACKQ;
 		}
 		e = -1;
-		savehandler = handler;
-		savecmdname = commandname;
-		handler = &jmploc;
+		savehandler = psh->handler;
+		savecmdname = psh->commandname;
+		psh->handler = &jmploc;
 		if (!setjmp(jmploc.loc)) {
 			/* We need to ensure the command hash table isn't
@@ -1002,24 +1003,25 @@
 			 * However we must ensure the 'local' command works!
 			 */
-			if (path != pathval() && (cmdentry.u.bltin == hashcmd ||
+			if (path != pathval(psh) && (cmdentry.u.bltin == hashcmd ||
 			    cmdentry.u.bltin == typecmd)) {
-				savelocalvars = localvars;
-				localvars = 0;
-				mklocal(path - 5 /* PATH= */, 0);
+				savelocalvars = psh->localvars;
+				psh->localvars = 0;
+				mklocal(psh, path - 5 /* PATH= */, 0);
 				temp_path = 1;
 			} else
 				temp_path = 0;
-			redirect(cmd->ncmd.redirect, mode);
+			redirect(psh, cmd->ncmd.redirect, mode);
 
 			/* exec is a special builtin, but needs this list... */
-			cmdenviron = varlist.list;
+			psh->cmdenviron = varlist.list;
 			/* we must check 'readonly' flag for all builtins */
-			listsetvar(varlist.list,
+			listsetvar(psh, varlist.list,
 				cmdentry.cmdtype == CMDSPLBLTIN ? 0 : VNOSET);
-			commandname = argv[0];
+			psh->commandname = argv[0];
 			/* initialize nextopt */
-			argptr = argv + 1;
-			optptr = NULL;
+			psh->argptr = argv + 1;
+			psh->optptr = NULL;
 			/* and getopt */
+/** @todo fix getop usage! */
 #if defined(__FreeBSD__) || defined(__EMX__) || defined(__APPLE__)
 			optreset = 1;
@@ -1029,37 +1031,37 @@
 #endif
 
-			exitstatus = cmdentry.u.bltin(argc, argv);
+			psh->exitstatus = cmdentry.u.bltin(psh, argc, argv);
 		} else {
-			e = exception;
-			exitstatus = e == EXINT ? SIGINT + 128 :
-					e == EXEXEC ? exerrno : 2;
-		}
-		handler = savehandler;
-		output_flushall();
-		out1 = &output;
-		out2 = &errout;
-		freestdout();
+			e = psh->exception;
+			psh->exitstatus = e == EXINT ? SIGINT + 128 :
+					e == EXEXEC ? psh->exerrno : 2;
+		}
+		psh->handler = savehandler;
+		output_flushall(psh);
+		psh->out1 = &psh->output;
+		psh->out2 = &psh->errout;
+		freestdout(psh);
 		if (temp_path) {
-			poplocalvars();
-			localvars = savelocalvars;
-		}
-		cmdenviron = NULL;
+			poplocalvars(psh);
+			psh->localvars = savelocalvars;
+		}
+		psh->cmdenviron = NULL;
 		if (e != EXSHELLPROC) {
-			commandname = savecmdname;
+			psh->commandname = savecmdname;
 			if (flags & EV_EXIT)
-				exitshell(exitstatus);
+				exitshell(psh, psh->exitstatus);
 		}
 		if (e != -1) {
 			if ((e != EXERROR && e != EXEXEC)
 			    || cmdentry.cmdtype == CMDSPLBLTIN)
-				exraise(e);
+				exraise(psh, e);
 			FORCEINTON;
 		}
 		if (cmdentry.u.bltin != execcmd)
-			popredir();
+			popredir(psh);
 		if (flags == EV_BACKCMD) {
-			backcmd->buf = memout.buf;
-			backcmd->nleft = memout.nextc - memout.buf;
-			memout.buf = NULL;
+			backcmd->buf = psh->memout.buf;
+			backcmd->nleft = psh->memout.nextc - psh->memout.buf;
+			psh->memout.buf = NULL;
 		}
 		break;
@@ -1069,11 +1071,11 @@
 		trputs("normal command:  ");  trargs(argv);
 #endif
-		clearredir(vforked);
-		redirect(cmd->ncmd.redirect, vforked ? REDIR_VFORK : 0);
-		if (!vforked)
+		clearredir(psh, psh->vforked);
+		redirect(psh, cmd->ncmd.redirect, psh->vforked ? REDIR_VFORK : 0);
+		if (!psh->vforked)
 			for (sp = varlist.list ; sp ; sp = sp->next)
-				setvareq(sp->text, VEXPORT|VSTACK);
-		envp = environment();
-		shellexec(argv, envp, path, cmdentry.u.index, vforked);
+				setvareq(psh, sp->text, VEXPORT|VSTACK);
+		envp = environment(psh);
+		shellexec(psh, argv, envp, path, cmdentry.u.index, psh->vforked);
 		break;
 	}
@@ -1082,8 +1084,8 @@
 parent:	/* parent process gets here (if we forked) */
 	if (mode == FORK_FG) {	/* argument to fork */
-		exitstatus = waitforjob(jp);
+		psh->exitstatus = waitforjob(psh, jp);
 	} else if (mode == FORK_NOJOB) {
 		backcmd->fd = pip[0];
-		close(pip[1]);
+		shfile_close(&psh->fdtab, pip[1]);
 		backcmd->jp = jp;
 	}
@@ -1096,9 +1098,9 @@
 		 * However I implemented that within libedit itself.
 		 */
-		setvar("_", lastarg, 0);
-	popstackmark(&smark);
-
-	if (eflag && exitstatus && !(flags & EV_TESTED))
-		exitshell(exitstatus);
+		setvar(psh, "_", lastarg, 0);
+	popstackmark(psh, &smark);
+
+	if (psh->eflag && psh->exitstatus && !(flags & EV_TESTED))
+		exitshell(psh, psh->exitstatus);
 }
 
@@ -1112,5 +1114,5 @@
 
 STATIC void
-prehash(union node *n)
+prehash(shinstance *psh, union node *n)
 {
 	struct cmdentry entry;
@@ -1118,6 +1120,6 @@
 	if (n->type == NCMD && n->ncmd.args)
 		if (goodname(n->ncmd.args->narg.text))
-			find_command(n->ncmd.args->narg.text, &entry, 0,
-				     pathval());
+			find_command(psh, n->ncmd.args->narg.text, &entry, 0,
+				     pathval(psh));
 }
 
@@ -1134,11 +1136,11 @@
 
 int
-bltincmd(int argc, char **argv)
+bltincmd(shinstance *psh, int argc, char **argv)
 {
 	/*
-	 * Preserve exitstatus of a previous possible redirection
+	 * Preserve psh->exitstatus of a previous possible redirection
 	 * as POSIX mandates
 	 */
-	return back_exitstatus;
+	return psh->exitstatus;
 }
 
@@ -1146,5 +1148,5 @@
 /*
  * Handle break and continue commands.  Break, continue, and return are
- * all handled by setting the evalskip flag.  The evaluation routines
+ * all handled by setting the psh->evalskip flag.  The evaluation routines
  * above all check this flag, and if it is set they start skipping
  * commands rather than executing them.  The variable skipcount is
@@ -1156,13 +1158,13 @@
 
 int
-breakcmd(int argc, char **argv)
+breakcmd(shinstance *psh, int argc, char **argv)
 {
 	int n = argc > 1 ? number(argv[1]) : 1;
 
-	if (n > loopnest)
-		n = loopnest;
+	if (n > psh->loopnest)
+		n = psh->loopnest;
 	if (n > 0) {
-		evalskip = (**argv == 'c')? SKIPCONT : SKIPBREAK;
-		skipcount = n;
+		psh->evalskip = (**argv == 'c')? SKIPCONT : SKIPBREAK;
+		psh->skipcount = n;
 	}
 	return 0;
@@ -1175,17 +1177,17 @@
 
 int
-returncmd(int argc, char **argv)
-{
-	int ret = argc > 1 ? number(argv[1]) : exitstatus;
-
-	if (funcnest) {
-		evalskip = SKIPFUNC;
-		skipcount = 1;
+returncmd(shinstance *psh, int argc, char **argv)
+{
+	int ret = argc > 1 ? number(argv[1]) : psh->exitstatus;
+
+	if (psh->funcnest) {
+		psh->evalskip = SKIPFUNC;
+		psh->skipcount = 1;
 		return ret;
 	}
 	else {
 		/* Do what ksh does; skip the rest of the file */
-		evalskip = SKIPFILE;
-		skipcount = 1;
+		psh->evalskip = SKIPFILE;
+		psh->skipcount = 1;
 		return ret;
 	}
@@ -1194,5 +1196,5 @@
 
 int
-falsecmd(int argc, char **argv)
+falsecmd(shinstance *psh, int argc, char **argv)
 {
 	return 1;
@@ -1201,5 +1203,5 @@
 
 int
-truecmd(int argc, char **argv)
+truecmd(shinstance *psh, int argc, char **argv)
 {
 	return 0;
@@ -1208,15 +1210,15 @@
 
 int
-execcmd(int argc, char **argv)
+execcmd(shinstance *psh, int argc, char **argv)
 {
 	if (argc > 1) {
 		struct strlist *sp;
 
-		iflag = 0;		/* exit on error */
-		mflag = 0;
-		optschanged();
-		for (sp = cmdenviron; sp; sp = sp->next)
-			setvareq(sp->text, VEXPORT|VSTACK);
-		shellexec(argv + 1, environment(), pathval(), 0, 0);
+		psh->iflag = 0;		/* exit on error */
+		psh->mflag = 0;
+		optschanged(psh);
+		for (sp = psh->cmdenviron; sp; sp = sp->next)
+			setvareq(psh, sp->text, VEXPORT|VSTACK);
+		shellexec(psh, argv + 1, environment(psh), pathval(psh), 0, 0);
 	}
 	return 0;
@@ -1231,5 +1233,5 @@
 
 	if (!tpm)
-		tpm = sysconf(_SC_CLK_TCK) * 60;
+		tpm = /*sysconf(_SC_CLK_TCK)*/sh_sysconf_clk_tck() * 60;
 
 	mins = ticks / tpm;
@@ -1251,13 +1253,13 @@
 
 int
-timescmd(int argc, char **argv)
-{
-	struct tms tms;
+timescmd(shinstance *psh, int argc, char **argv)
+{
+	struct sh_tms tms;
 	int u, s, cu, cs;
 	char us[8], ss[8], cus[8], css[8];
 
-	nextopt("");
-
-	times(&tms);
+	nextopt(psh, "");
+
+	sh_times(&tms);
 
 	u = conv_time(tms.tms_utime, us, sizeof(us));
@@ -1266,5 +1268,5 @@
 	cs = conv_time(tms.tms_cstime, css, sizeof(css));
 
-	outfmt(out1, "%dm%ss %dm%ss\n%dm%ss %dm%ss\n",
+	outfmt(psh->out1, "%dm%ss %dm%ss\n%dm%ss %dm%ss\n",
 		u, us, s, ss, cu, cus, cs, css);
 
Index: /trunk/src/ash-messup/exec.h
===================================================================
--- /trunk/src/ash-messup/exec.h	(revision 883)
+++ /trunk/src/ash-messup/exec.h	(revision 884)
@@ -47,5 +47,5 @@
 	union param {
 		int index;
-		int (*bltin)(int, char**);
+		int (*bltin)(struct shinstance*, int, char**);
 		union node *func;
 	} u;
Index: /trunk/src/ash-messup/expand.h
===================================================================
--- /trunk/src/ash-messup/expand.h	(revision 883)
+++ /trunk/src/ash-messup/expand.h	(revision 884)
@@ -68,5 +68,5 @@
 /* From arith.y */
 int arith(const char *);
-int expcmd(int , char **);
+int expcmd(struct shinstance *, int , char **);
 void arith_lex_reset(void);
 int yylex(void);
Index: /trunk/src/ash-messup/generated/builtins.h
===================================================================
--- /trunk/src/ash-messup/generated/builtins.h	(revision 883)
+++ /trunk/src/ash-messup/generated/builtins.h	(revision 884)
@@ -7,5 +7,5 @@
 struct builtincmd {
       const char *name;
-      int (*builtin)(int, char **);
+      int (*builtin)(struct shinstance *, int, char **);
 };
 
@@ -14,44 +14,44 @@
 
 
-int bltincmd(int, char **);
-int bgcmd(int, char **);
-int breakcmd(int, char **);
-int cdcmd(int, char **);
-int dotcmd(int, char **);
-int echocmd(int, char **);
-int evalcmd(int, char **);
-int execcmd(int, char **);
-int exitcmd(int, char **);
-int expcmd(int, char **);
-int exportcmd(int, char **);
-int falsecmd(int, char **);
-int histcmd(int, char **);
-int inputrc(int, char **);
-int fgcmd(int, char **);
-int getoptscmd(int, char **);
-int hashcmd(int, char **);
-int jobidcmd(int, char **);
-int jobscmd(int, char **);
-int localcmd(int, char **);
+int bltincmd(struct shinstance *, int, char **);
+int bgcmd(struct shinstance *, int, char **);
+int breakcmd(struct shinstance *, int, char **);
+int cdcmd(struct shinstance *, int, char **);
+int dotcmd(struct shinstance *, int, char **);
+int echocmd(struct shinstance *, int, char **);
+int evalcmd(struct shinstance *, int, char **);
+int execcmd(struct shinstance *, int, char **);
+int exitcmd(struct shinstance *, int, char **);
+int expcmd(struct shinstance *, int, char **);
+int exportcmd(struct shinstance *, int, char **);
+int falsecmd(struct shinstance *, int, char **);
+int histcmd(struct shinstance *, int, char **);
+int inputrc(struct shinstance *, int, char **);
+int fgcmd(struct shinstance *, int, char **);
+int getoptscmd(struct shinstance *, int, char **);
+int hashcmd(struct shinstance *, int, char **);
+int jobidcmd(struct shinstance *, int, char **);
+int jobscmd(struct shinstance *, int, char **);
+int localcmd(struct shinstance *, int, char **);
 #ifndef SMALL
-int printfcmd(int, char **);
+int printfcmd(struct shinstance *, int, char **);
 #endif
-int pwdcmd(int, char **);
-int readcmd(int, char **);
-int returncmd(int, char **);
-int setcmd(int, char **);
-int setvarcmd(int, char **);
-int shiftcmd(int, char **);
-int timescmd(int, char **);
-int trapcmd(int, char **);
-int truecmd(int, char **);
-int typecmd(int, char **);
-int umaskcmd(int, char **);
-int unaliascmd(int, char **);
-int unsetcmd(int, char **);
-int waitcmd(int, char **);
-int aliascmd(int, char **);
-int ulimitcmd(int, char **);
-int testcmd(int, char **);
-int killcmd(int, char **);
-int wordexpcmd(int, char **);
+int pwdcmd(struct shinstance *, int, char **);
+int readcmd(struct shinstance *, int, char **);
+int returncmd(struct shinstance *, int, char **);
+int setcmd(struct shinstance *, int, char **);
+int setvarcmd(struct shinstance *, int, char **);
+int shiftcmd(struct shinstance *, int, char **);
+int timescmd(struct shinstance *, int, char **);
+int trapcmd(struct shinstance *, int, char **);
+int truecmd(struct shinstance *, int, char **);
+int typecmd(struct shinstance *, int, char **);
+int umaskcmd(struct shinstance *, int, char **);
+int unaliascmd(struct shinstance *, int, char **);
+int unsetcmd(struct shinstance *, int, char **);
+int waitcmd(struct shinstance *, int, char **);
+int aliascmd(struct shinstance *, int, char **);
+int ulimitcmd(struct shinstance *, int, char **);
+int testcmd(struct shinstance *, int, char **);
+int killcmd(struct shinstance *, int, char **);
+int wordexpcmd(struct shinstance *, int, char **);
Index: /trunk/src/ash-messup/main.c
===================================================================
--- /trunk/src/ash-messup/main.c	(revision 883)
+++ /trunk/src/ash-messup/main.c	(revision 884)
@@ -342,5 +342,5 @@
 
 	INTOFF;
-	if ((fd = open(name, O_RDONLY)) >= 0)
+	if ((fd = shfile_open(&psh->fdtab, name, O_RDONLY)) >= 0)
 		setinputfd(psh, fd, 1);
 	else
@@ -371,5 +371,5 @@
 
 	while ((fullname = padvance(psh, &path, basename)) != NULL) {
-		if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) {
+		if ((shfile_stat(&psh->fdtab, fullname, &statb) == 0) && S_ISREG(statb.st_mode)) {
 			/*
 			 * Don't bother freeing here, since it will
Index: /trunk/src/ash-messup/memalloc.h
===================================================================
--- /trunk/src/ash-messup/memalloc.h	(revision 883)
+++ /trunk/src/ash-messup/memalloc.h	(revision 884)
@@ -73,5 +73,5 @@
 #define STTOPC(p)	p[-1]
 #define STADJUST(amount, p)	(p += (amount), psh->sstrnleft -= (amount))
-#define grabstackstr(p)	stalloc(stackblocksize() - psh->sstrnleft)
+#define grabstackstr(p)	stalloc(psh, stackblocksize() - psh->sstrnleft)
 
 #define ckfree(p)	free((pointer)(p))
Index: /trunk/src/ash-messup/options.h
===================================================================
--- /trunk/src/ash-messup/options.h	(revision 883)
+++ /trunk/src/ash-messup/options.h	(revision 884)
@@ -130,5 +130,5 @@
 void optschanged(struct shinstance *);
 void setparam(struct shinstance *, char **);
-void freeparam(struct shinstance *, volatile struct shparam *);
+void freeparam(volatile struct shparam *);
 int shiftcmd(struct shinstance *, int, char **);
 int setcmd(struct shinstance *, int, char **);
Index: /trunk/src/ash-messup/parser.h
===================================================================
--- /trunk/src/ash-messup/parser.h	(revision 883)
+++ /trunk/src/ash-messup/parser.h	(revision 884)
@@ -79,4 +79,4 @@
 union node *parsecmd(struct shinstance *, int);
 void fixredir(struct shinstance *, union node *, const char *, int);
-int goodname(struct shinstance *, char *);
+int goodname(char *);
 const char *getprompt(struct shinstance *, void *);
Index: /trunk/src/ash-messup/shfile.h
===================================================================
--- /trunk/src/ash-messup/shfile.h	(revision 883)
+++ /trunk/src/ash-messup/shfile.h	(revision 884)
@@ -53,5 +53,17 @@
 
 int shfile_open(shfdtab *, const char *, unsigned);
+int shfile_pipe(shfdtab *, int [2]);
 int shfile_close(shfdtab *, unsigned);
+int shfile_fcntl(shfdtab *, int fd, int cmd, int arg);
+#ifdef _MSC_VER
+# define F_DUPFD    0
+# define F_GETFD    1
+# define F_SETFD    2
+# define F_GETFL    3
+# define F_SETFL    4
+# define FD_CLOEXEC 1
+#else
+# include <sys/fcntl.h>
+#endif
 
 int shfile_stat(shfdtab *, const char *, struct stat *);
Index: /trunk/src/ash-messup/shinstance.h
===================================================================
--- /trunk/src/ash-messup/shinstance.h	(revision 883)
+++ /trunk/src/ash-messup/shinstance.h	(revision 884)
@@ -138,6 +138,8 @@
     int                 back_exitstatus;/**< exit status of backquoted command */
     struct strlist     *cmdenviron;     /**< environment for builtin command */
-    int                 funcnest;
-    int                 evalskip;
+    int                 funcnest;       /**< depth of function calls */
+    int                 evalskip;       /**< set if we are skipping commands */
+    int                 skipcount;      /**< number of levels to skip */
+    int                 loopnest;       /**< current loop nesting level */
 
     /* builtins.h */
@@ -156,4 +158,6 @@
     char                errmsg_buf[16]; /**< static in errmsg. (bss) */
 
+    /* eval.c */
+    int                 vforked;
 } shinstance;
 
@@ -165,7 +169,7 @@
 #include <signal.h>
 #ifdef _MSC_VER
-typedef uint32_t sh_sigset_t;
+    typedef uint32_t sh_sigset_t;
 #else
-typedef sigset_t sh_sigset_t;
+    typedef sigset_t sh_sigset_t;
 #endif 
 
@@ -176,3 +180,46 @@
 int sh_sigprocmask(shinstance *, int op, sh_sigset_t const *new, sh_sigset_t *old);
 
-#endif
+/* times */
+#include <time.h>
+#ifdef _MSC_VER
+    typedef struct sh_tms
+    {
+        clock_t tms_utime;
+        clock_t tms_stime;
+        clock_t tms_cutime;
+        clock_t tms_cstime;
+    } sh_tms;
+#else
+#   include <times.h>
+    typedef struct tms sh_tms;
+#endif 
+clock_t sh_times(sh_tms *);
+int sh_sysconf_clk_tck(void);
+
+/* wait */
+#ifdef _MSC_VER
+#   include <process.h>
+#   define WNOHANG         1       /* Don't hang in wait. */
+#   define WUNTRACED       2       /* Tell about stopped, untraced children. */
+#   define WCONTINUED      4       /* Report a job control continued process. */
+#   define _W_INT(w)       (*(int *)&(w))  /* Convert union wait to int. */
+#   define WCOREFLAG       0200
+#   define _WSTATUS(x)     (_W_INT(x) & 0177)
+#   define _WSTOPPED       0177            /* _WSTATUS if process is stopped */
+#   define WIFSTOPPED(x)   (_WSTATUS(x) == _WSTOPPED)
+#   define WSTOPSIG(x)     (_W_INT(x) >> 8)
+#   define WIFSIGNALED(x)  (_WSTATUS(x) != 0 && !WIFSTOPPED(x) && !WIFCONTINUED(x)) /* bird: made GLIBC tests happy. */
+#   define WTERMSIG(x)     (_WSTATUS(x))
+#   define WIFEXITED(x)    (_WSTATUS(x) == 0)
+#   define WEXITSTATUS(x)  (_W_INT(x) >> 8)
+#   define WIFCONTINUED(x) (x == 0x13)     /* 0x13 == SIGCONT */
+#   define WCOREDUMP(x)    (_W_INT(x) & WCOREFLAG)
+#   define W_EXITCODE(ret, sig)    ((ret) << 8 | (sig))
+#   define W_STOPCODE(sig)         ((sig) << 8 | _WSTOPPED)
+#else
+#   include <sys/wait.h>
+#endif 
+pid_t sh_waitpid(shinstance *, pid_t, int *, int);
+void sh__exit(shinstance *, int);
+
+#endif
Index: /trunk/src/ash-messup/var.h
===================================================================
--- /trunk/src/ash-messup/var.h	(revision 883)
+++ /trunk/src/ash-messup/var.h	(revision 884)
@@ -34,4 +34,7 @@
  *	@(#)var.h	8.2 (Berkeley) 5/4/95
  */
+
+#ifndef ___var_h___
+#define ___var_h___
 
 /*
@@ -143,2 +146,4 @@
 int setvarsafe(struct shinstance *, const char *, const char *, int);
 void print_quoted(struct shinstance *, const char *);
+
+#endif
