Index: trunk/src/kash/bltin/bltin.h
===================================================================
--- trunk/src/kash/bltin/bltin.h	(revision 1201)
+++ trunk/src/kash/bltin/bltin.h	(revision 1202)
@@ -75,5 +75,5 @@
 #define setlocate(l,s) 0
 
-#define getenv(p) bltinlookup((p),0)
+#define getenv(p) bltinlookup(psh, (p),0)
 
 #else
Index: trunk/src/kash/bltin/kill.c
===================================================================
--- trunk/src/kash/bltin/kill.c	(revision 1201)
+++ trunk/src/kash/bltin/kill.c	(revision 1202)
@@ -153,7 +153,7 @@
 	for (errors = 0; argc; argc--, argv++) {
 #ifdef SHELL
-		extern int getjobpgrp(const char *);
+		extern int getjobpgrp(shinstance *psh, const char *);
 		if (*argv[0] == '%') {
-			pid = getjobpgrp(*argv);
+			pid = getjobpgrp(psh, *argv);
 			if (pid == 0) {
 				warnx("illegal job id: %s", *argv);
Index: trunk/src/kash/exec.c
===================================================================
--- trunk/src/kash/exec.c	(revision 1201)
+++ trunk/src/kash/exec.c	(revision 1202)
@@ -229,5 +229,5 @@
 		}
 #endif
-		setparam(argv + 1);
+		setparam(psh, argv + 1);
 		exraise(psh, EXSHELLPROC);
 	}
@@ -437,5 +437,5 @@
 
 	verbose = 0;
-	while ((c = nextopt("rv")) != '\0') {
+	while ((c = nextopt(psh, "rv")) != '\0') {
 		if (c == 'r') {
 			clearcmdentry(0);
@@ -500,5 +500,5 @@
 			struct procstat ps;
 			INTOFF;
-			commandtext(&ps, cmdp->param.func);
+			commandtext(psh, &ps, cmdp->param.func);
 			INTON;
 			out1str(psh, "() { ");
@@ -665,5 +665,5 @@
 				goto loop;
 			stalloc(psh, strlen(fullname) + 1);
-			readcmdfile(fullname);
+			readcmdfile(psh, fullname);
 			if ((cmdp = cmdlookup(name, 0)) == NULL ||
 			    cmdp->cmdtype != CMDFUNCTION)
@@ -1085,5 +1085,5 @@
 	int p_flag = 0;
 
-	while ((c = nextopt("vVp")) != 0) {
+	while ((c = nextopt(psh, "vVp")) != 0) {
 		switch (c) {
 		case 'v': v_flag = 1; break;
Index: trunk/src/kash/expand.c
===================================================================
--- trunk/src/kash/expand.c	(revision 1201)
+++ trunk/src/kash/expand.c	(revision 1202)
@@ -288,5 +288,5 @@
 	*p = '\0';
 	if (*(startp+1) == '\0') {
-		if ((home = lookupvar("HOME")) == NULL)
+		if ((home = lookupvar(psh, "HOME")) == NULL)
 			goto lose;
 	} else {
@@ -477,5 +477,5 @@
 		ckfree(in.buf);
 	if (in.jp)
-		back_exitstatus = waitforjob(in.jp);
+		back_exitstatus = waitforjob(psh, in.jp);
 	if (quoted == 0)
 		recordregion(startloc, dest - stackblock(psh), 0);
@@ -512,5 +512,5 @@
 	switch (subtype) {
 	case VSASSIGN:
-		setvar(str, startp, 0);
+		setvar(psh, str, startp, 0);
 		amount = startp - expdest;
 		STADJUST(psh, amount, expdest);
@@ -639,5 +639,5 @@
 		val = NULL;
 	} else {
-		val = lookupvar(var);
+		val = lookupvar(psh, var);
 		if (val == NULL || ((varflags & VSNUL) && val[0] == '\0')) {
 			val = NULL;
Index: trunk/src/kash/generated/init.c
===================================================================
--- trunk/src/kash/generated/init.c	(revision 1201)
+++ trunk/src/kash/generated/init.c	(revision 1202)
@@ -189,8 +189,8 @@
 	      char **envp;
 
-	      initvar();
+	      initvar(psh);
 	      for (envp = environ ; *envp ; envp++) {
 		      if (strchr(*envp, '=')) {
-			      setvareq(*envp, VEXPORT|VTEXTFIXED);
+			      setvareq(psh, *envp, VEXPORT|VTEXTFIXED);
 		      }
 	      }
@@ -241,5 +241,5 @@
       {
 	      while (redirlist)
-		      popredir();
+		      popredir(psh);
       }
 }
@@ -288,5 +288,5 @@
 	      for (i = 0; optlist[i].name; i++)
 		      optlist[i].val = 0;
-	      optschanged();
+	      optschanged(psh);
 
       }
@@ -294,5 +294,5 @@
       /* from redir.c: */
       {
-	      clearredir(0);
+	      clearredir(psh, 0);
       }
 
@@ -301,5 +301,5 @@
 	      char *sm;
 
-	      clear_traps(0);
+	      clear_traps(psh, 0);
 	      for (sm = sigmode ; sm < sigmode + NSIG ; sm++) {
 		      if (*sm == S_IGN)
@@ -310,5 +310,5 @@
       /* from var.c: */
       {
-	      shprocvar();
+	      shprocvar(psh);
       }
 }
Index: trunk/src/kash/histedit.c
===================================================================
--- trunk/src/kash/histedit.c	(revision 1201)
+++ trunk/src/kash/histedit.c	(revision 1202)
@@ -125,5 +125,5 @@
 				el_err = tracefile;
 #endif
-			term = lookupvar("TERM");
+			term = lookupvar(psh, "TERM");
 			if (term)
 				setenv("TERM", term, 1);
@@ -322,6 +322,6 @@
 		if (sflg == 0) {
 			if (editor == NULL &&
-			    (editor = bltinlookup("FCEDIT", 1)) == NULL &&
-			    (editor = bltinlookup("EDITOR", 1)) == NULL)
+			    (editor = bltinlookup(psh, "FCEDIT", 1)) == NULL &&
+			    (editor = bltinlookup(psh, "EDITOR", 1)) == NULL)
 				editor = DEFEDITOR;
 			if (editor[0] == '-' && editor[1] == '\0') {
@@ -444,5 +444,5 @@
 		evalstring(psh, editcmd, 0);	/* XXX - should use no JC command */
 		INTON;
-		readcmdfile(editfile);	/* XXX - should read back - quick tst */
+		readcmdfile(psh, editfile);	/* XXX - should read back - quick tst */
 		unlink(editfile);
 	}
Index: trunk/src/kash/jobs.c
===================================================================
--- trunk/src/kash/jobs.c	(revision 1201)
+++ trunk/src/kash/jobs.c	(revision 1202)
@@ -116,8 +116,8 @@
 
 static pid_t
-tcgetpgrp(int fd)
+tcgetpgrp(shinstance *psh, int fd)
 {
 	pid_t pgrp;
-	if (ioctl(fd, TIOCGPGRP, (char *)&pgrp) == -1)
+	if (shfile_ioctl(&psh->fdtab, fd, TIOCGPGRP, (char *)&pgrp) == -1)
 		return -1;
 	else
@@ -126,7 +126,7 @@
 
 static int
-tcsetpgrp(int fd, pid_tpgrp)
-{
-	return ioctl(fd, TIOCSPGRP, (char *)&pgrp);
+tcsetpgrp(shinstance *psh, int fd, pid_tpgrp)
+{
+	return shfile_ioctl(&psh->fdtab, fd, TIOCSPGRP, (char *)&pgrp);
 }
 #endif
@@ -212,7 +212,7 @@
 		}
 #endif
-		setsignal(SIGTSTP, 0);
-		setsignal(SIGTTOU, 0);
-		setsignal(SIGTTIN, 0);
+		setsignal(psh, SIGTSTP, 0);
+		setsignal(psh, SIGTTOU, 0);
+		setsignal(psh, SIGTTIN, 0);
 		if (getpgid(0) != rootpid && setpgid(0, rootpid) == -1)
 			error(psh, "Cannot set process group (%s) at %d",
@@ -230,7 +230,7 @@
 		close(ttyfd);
 		ttyfd = -1;
-		setsignal(SIGTSTP, 0);
-		setsignal(SIGTTOU, 0);
-		setsignal(SIGTTIN, 0);
+		setsignal(psh, SIGTSTP, 0);
+		setsignal(psh, SIGTTOU, 0);
+		setsignal(psh, SIGTTIN, 0);
 	}
 	jobctl = on;
@@ -254,5 +254,5 @@
 #if JOBS
 int
-fgcmd(int argc, char **argv)
+fgcmd(shinstance *psh, int argc, char **argv)
 {
 	struct job *jp;
@@ -260,6 +260,6 @@
 	int status;
 
-	nextopt("");
-	jp = getjob(*argptr, 0);
+	nextopt(psh, "");
+	jp = getjob(*psh->argptr, 0);
 	if (jp->jobctl == 0)
 		error(psh, "job not created under job control");
@@ -271,5 +271,5 @@
 
 	for (i = 0; i < jp->nprocs; i++)
-	    if (tcsetpgrp(ttyfd, jp->ps[i].pid) != -1)
+	    if (tcsetpgrp(psh, ttyfd, jp->ps[i].pid) != -1)
 		    break;
 
@@ -278,7 +278,7 @@
 		    strerror(errno), __LINE__);
 	}
-	restartjob(jp);
+	restartjob(psh, jp);
 	INTOFF;
-	status = waitforjob(jp);
+	status = waitforjob(psh, jp);
 	INTON;
 	return status;
@@ -338,5 +338,5 @@
 	int i;
 
-	nextopt("");
+	nextopt(psh, "");
 	do {
 		jp = getjob(psh, *psh->argptr, 0);
@@ -506,5 +506,5 @@
 	jobs_invalid = 0;
 	mode = 0;
-	while ((m = nextopt("lp")))
+	while ((m = nextopt(psh, "lp")))
 		if (m == 'l')
 			mode = SHOW_PID;
@@ -516,5 +516,5 @@
 		while (*++argptr);
 	else
-		showjobs(out1, mode);
+		showjobs(psh, out1, mode);
 	jobs_invalid = sv;
 	return 0;
@@ -606,5 +606,5 @@
 	struct job *jp;
 
-	nextopt("");
+	nextopt(psh, "");
 
 	if (!*argptr) {
@@ -665,5 +665,5 @@
 	int i;
 
-	nextopt("");
+	nextopt(psh, "");
 	jp = getjob(*argptr, 0);
 	for (i = 0 ; i < jp->nprocs ; ) {
@@ -858,8 +858,8 @@
 		break;
 	case 0:
-		forkchild(jp, n, mode, 0);
+		forkchild(psh, jp, n, mode, 0);
 		return 0;
 	default:
-		return forkparent(jp, n, mode, pid);
+		return forkparent(psh, jp, n, mode, pid);
 	}
 }
@@ -886,5 +886,5 @@
 		ps->cmd[0] = 0;
 		if (/* iflag && rootshell && */ n)
-			commandtext(ps, n);
+			commandtext(psh, ps, n);
 	}
 	TRACE((psh, "In parent shell:  child = %d\n", pid));
@@ -922,11 +922,11 @@
 				    strerror(errno), __LINE__);
 		}
-		setsignal(SIGTSTP, vforked);
-		setsignal(SIGTTOU, vforked);
+		setsignal(psh, SIGTSTP, vforked);
+		setsignal(psh, SIGTTOU, vforked);
 	} else if (mode == FORK_BG) {
-		ignoresig(SIGINT, vforked);
-		ignoresig(SIGQUIT, vforked);
+		ignoresig(psh, SIGINT, vforked);
+		ignoresig(psh, SIGQUIT, vforked);
 		if ((jp == NULL || jp->nprocs == 0) &&
-		    ! fd0_redirected_p ()) {
+		    ! fd0_redirected_p(psh)) {
 			close(0);
 			if (open(devnull, O_RDONLY) != 0)
@@ -936,8 +936,8 @@
 #else
 	if (mode == FORK_BG) {
-		ignoresig(SIGINT, vforked);
-		ignoresig(SIGQUIT, vforked);
+		ignoresig(psh, SIGINT, vforked);
+		ignoresig(psh, SIGQUIT, vforked);
 		if ((jp == NULL || jp->nprocs == 0) &&
-		    ! fd0_redirected_p ()) {
+		    ! fd0_redirected_p(psh)) {
 			close(0);
 			if (open(devnull, O_RDONLY) != 0)
@@ -947,7 +947,7 @@
 #endif
 	if (wasroot && iflag(psh)) {
-		setsignal(SIGINT, vforked);
-		setsignal(SIGQUIT, vforked);
-		setsignal(SIGTERM, vforked);
+		setsignal(psh, SIGINT, vforked);
+		setsignal(psh, SIGQUIT, vforked);
+		setsignal(psh, SIGTERM, vforked);
 	}
 
Index: trunk/src/kash/miscbltin.c
===================================================================
--- trunk/src/kash/miscbltin.c	(revision 1201)
+++ trunk/src/kash/miscbltin.c	(revision 1202)
@@ -105,5 +105,5 @@
 	rflag = 0;
 	prompt = NULL;
-	while ((i = nextopt("p:r")) != '\0') {
+	while ((i = nextopt(psh, "p:r")) != '\0') {
 		if (i == 'p')
 			prompt = optionarg;
@@ -120,5 +120,5 @@
 		error(psh, "arg count");
 
-	if ((ifs = bltinlookup("IFS", 1)) == NULL)
+	if ((ifs = bltinlookup(psh, "IFS", 1)) == NULL)
 		ifs = " \t\n";
 
@@ -186,5 +186,5 @@
 
 		STACKSTRNUL(psh, p);
-		setvar(*ap, stackblock(psh), 0);
+		setvar(psh, *ap, stackblock(psh), 0);
 		ap++;
 		STARTSTACKSTR(psh, p);
@@ -203,9 +203,9 @@
 			break;
 	}
-	setvar(*ap, stackblock(psh), 0);
+	setvar(psh, *ap, stackblock(psh), 0);
 
 	/* Set any remaining args to "" */
 	while (*++ap != NULL)
-		setvar(*ap, nullstr, 0);
+		setvar(psh, *ap, nullstr, 0);
 	return status;
 }
@@ -221,5 +221,5 @@
 	int symbolic_mode = 0;
 
-	while ((i = nextopt("S")) != '\0') {
+	while ((i = nextopt(psh, "S")) != '\0') {
 		symbolic_mode = 1;
 	}
@@ -366,5 +366,5 @@
 
 	what = 'f';
-	while ((optc = nextopt("HSabtfdsmcnpl")) != '\0')
+	while ((optc = nextopt(psh, "HSabtfdsmcnpl")) != '\0')
 		switch (optc) {
 		case 'H':
Index: trunk/src/kash/redir.c
===================================================================
--- trunk/src/kash/redir.c	(revision 1201)
+++ trunk/src/kash/redir.c	(revision 1202)
@@ -225,5 +225,5 @@
 				memory[fd] = 1;
 			else
-				copyfd(redir->ndup.dupfd, fd);
+				copyfd(psh, redir->ndup.dupfd, fd);
 		}
 		INTON;
@@ -238,6 +238,6 @@
 
 	if (f != fd) {
-		copyfd(f, fd);
-		close(f);
+		copyfd(psh, f, fd);
+		shfile_close(&psh->fdtab, f);
 	}
 	INTON;
@@ -271,5 +271,5 @@
 		}
 	}
-	if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
+	if (forkshell(psh, (struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) {
 		close(pip[0]);
 		signal(SIGINT, SIG_IGN);
@@ -307,8 +307,8 @@
                         if (i == 0)
                                 fd0_redirected--;
-			close(i);
+			shfile_close(&psh->fdtab, i);
 			if (rp->renamed[i] >= 0) {
-				copyfd(rp->renamed[i], i);
-				close(rp->renamed[i]);
+				copyfd(psh, rp->renamed[i], i);
+				shfile_close(&psh->fdtab, rp->renamed[i]);
 			}
 		}
@@ -330,9 +330,9 @@
 RESET {
 	while (redirlist)
-		popredir();
+		popredir(psh);
 }
 
 SHELLPROC {
-	clearredir(0);
+	clearredir(psh, 0);
 }
 
@@ -341,6 +341,6 @@
 /* Return true if fd 0 has already been redirected at least once.  */
 int
-fd0_redirected_p () {
-        return fd0_redirected != 0;
+fd0_redirected_p(shinstance *psh) {
+        return psh->fd0_redirected != 0;
 }
 
@@ -376,9 +376,9 @@
 
 int
-copyfd(int from, int to)
+copyfd(shinstance *psh, int from, int to)
 {
 	int newfd;
 
-	newfd = fcntl(from, F_DUPFD, to);
+	newfd = shfile_fcntl(psh, from, F_DUPFD, to);
 	if (newfd < 0) {
 		if (errno == EMFILE)
Index: trunk/src/kash/trap.c
===================================================================
--- trunk/src/kash/trap.c	(revision 1201)
+++ trunk/src/kash/trap.c	(revision 1202)
@@ -159,5 +159,5 @@
 			if (trap[signo] != NULL) {
 				out1fmt(psh, "trap -- ");
-				print_quoted(trap[signo]);
+				print_quoted(psh, trap[signo]);
 				out1fmt(psh, " %s\n",
 				    (signo) ? sys_signame[signo] : "EXIT");
@@ -207,5 +207,5 @@
 
 		if (signo != 0)
-			setsignal(signo, 0);
+			setsignal(psh, signo, 0);
 		INTON;
 		ap++;
@@ -235,5 +235,5 @@
 			}
 			if (tp != &trap[0])
-				setsignal(tp - trap, vforked);
+				setsignal(psh, tp - trap, vforked);
 			INTON;
 		}
@@ -360,5 +360,5 @@
 	char *sm;
 
-	clear_traps(0);
+	clear_traps(psh, s0);
 	for (sm = sigmode ; sm < sigmode + NSIG ; sm++) {
 		if (*sm == S_IGN)
@@ -429,7 +429,7 @@
 	if (on == is_interactive)
 		return;
-	setsignal(SIGINT, 0);
-	setsignal(SIGQUIT, 0);
-	setsignal(SIGTERM, 0);
+	setsignal(psh, SIGINT, 0);
+	setsignal(psh, SIGQUIT, 0);
+	setsignal(psh, SIGTERM, 0);
 	is_interactive = on;
 }
@@ -462,5 +462,5 @@
 	output_flushall(psh);
 #if JOBS
-	setjobctl(0);
+	setjobctl(psh, 0);
 #endif
 l2:   _exit(status);
Index: trunk/src/kash/var.c
===================================================================
--- trunk/src/kash/var.c	(revision 1201)
+++ trunk/src/kash/var.c	(revision 1202)
@@ -195,8 +195,8 @@
 	char **envp;
 
-	initvar();
+	initvar(psh);
 	for (envp = environ ; *envp ; envp++) {
 		if (strchr(*envp, '=')) {
-			setvareq(*envp, VEXPORT|VTEXTFIXED);
+			setvareq(psh, *envp, VEXPORT|VTEXTFIXED);
 		}
 	}
@@ -295,5 +295,5 @@
 	else {
 		handler = &jmploc;
-		setvar(name, val, flags);
+		setvar(psh, name, val, flags);
 	}
 	handler = savehandler;
@@ -347,5 +347,5 @@
 	if (val)
 		scopy(val, d);
-	setvareq(nameeq, flags);
+	setvareq(psh, nameeq, flags);
 }
 
@@ -394,5 +394,5 @@
 		 */
 		if (vp == &vmpath || (vp == &vmail && ! mpathset()))
-			chkmail(1);
+			chkmail(psh, 1);
 		INTON;
 		return;
@@ -423,5 +423,5 @@
 	INTOFF;
 	for (lp = list ; lp ; lp = lp->next) {
-		setvareq(savestr(lp->text), flags);
+		setvareq(psh, savestr(lp->text), flags);
 	}
 	INTON;
@@ -434,5 +434,5 @@
 
 	for (lp = list ; lp ; lp = lp->next)
-		mklocal(lp->text, flags);
+		mklocal(psh, lp->text, flags);
 }
 
@@ -528,18 +528,18 @@
 
 #ifdef mkinit
-void shprocvar(void);
+void shprocvar(shinstance *psh);
 
 SHELLPROC {
-	shprocvar();
+	shprocvar(psh);
 }
 #endif
 
 void
-shprocvar(void)
+shprocvar(shinstance *psh)
 {
 	struct var **vpp;
 	struct var *vp, **prev;
 
-	for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
+	for (vpp = psh->vartab ; vpp < psh->vartab + VTABSIZE ; vpp++) {
 		for (prev = vpp ; (vp = *prev) != NULL ; ) {
 			if ((vp->flags & VEXPORT) == 0) {
@@ -558,5 +558,5 @@
 		}
 	}
-	initvar();
+	initvar(psh);
 }
 
@@ -675,7 +675,7 @@
 	int pflag;
 
-	pflag = nextopt("p") == 'p' ? 3 : 0;
+	pflag = nextopt(psh, "p") == 'p' ? 3 : 0;
 	if (argc <= 1 || pflag) {
-		showvars( pflag ? argv[0] : 0, flag, pflag );
+		showvars(psh, pflag ? argv[0] : 0, flag, pflag );
 		return 0;
 	}
@@ -691,5 +691,5 @@
 			}
 		}
-		setvar(name, p, flag);
+		setvar(psh, name, p, flag);
 	}
 	return 0;
@@ -709,5 +709,5 @@
 		error(psh, "Not in a function");
 	while ((name = *argptr++) != NULL) {
-		mklocal(name, 0);
+		mklocal(psh, name, 0);
 	}
 	return 0;
@@ -740,7 +740,7 @@
 		if (vp == NULL) {
 			if (strchr(name, '='))
-				setvareq(savestr(name), VSTRFIXED|flags);
+				setvareq(psh, savestr(name), VSTRFIXED|flags);
 			else
-				setvar(name, NULL, VSTRFIXED|flags);
+				setvar(psh, name, NULL, VSTRFIXED|flags);
 			vp = *vpp;	/* the new variable */
 			lvp->text = NULL;
@@ -751,5 +751,5 @@
 			vp->flags |= VSTRFIXED|VTEXTFIXED;
 			if (name[vp->name_len] == '=')
-				setvareq(savestr(name), flags);
+				setvareq(psh, savestr(name), flags);
 		}
 	}
@@ -779,5 +779,5 @@
 			ckfree(lvp->text);
 		} else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) {
-			(void)unsetvar(vp->text, 0);
+			(void)unsetvar(psh, vp->text, 0);
 		} else {
 			if (vp->func && (vp->flags & VNOFUNC) == 0)
@@ -797,7 +797,7 @@
 {
 	if (argc <= 2)
-		return unsetcmd(argc, argv);
+		return unsetcmd(psh, argc, argv);
 	else if (argc == 3)
-		setvar(argv[1], argv[2], 0);
+		setvar(psh, argv[1], argv[2], 0);
 	else
 		error(psh, "List assignment not implemented");
@@ -821,5 +821,5 @@
 	int ret = 0;
 
-	while ((i = nextopt("evf")) != '\0') {
+	while ((i = nextopt(psh, "evf")) != '\0') {
 		if (i == 'f')
 			flg_func = 1;
@@ -862,5 +862,5 @@
 	} else {
 		if (vp->text[vp->name_len + 1] != '\0')
-			setvar(s, nullstr, 0);
+			setvar(psh, s, nullstr, 0);
 		vp->flags &= ~VEXPORT;
 		vp->flags |= VUNSET;
Index: trunk/src/kash/var.h
===================================================================
--- trunk/src/kash/var.h	(revision 1201)
+++ trunk/src/kash/var.h	(revision 1202)
@@ -86,5 +86,5 @@
 #ifdef _MSC_VER
 extern struct var vpath2;
-#endif 
+#endif
 extern struct var vps1;
 extern struct var vps2;
