Index: /trunk/src/kash/alias.c
===================================================================
--- /trunk/src/kash/alias.c	(revision 2289)
+++ /trunk/src/kash/alias.c	(revision 2290)
@@ -71,6 +71,6 @@
 		if (equal(name, ap->name)) {
 			INTOFF;
-			ckfree(ap->val);
-			ap->val	= savestr(val);
+			ckfree(psh, ap->val);
+			ap->val	= savestr(psh, val);
 			INTON;
 			return;
@@ -79,6 +79,6 @@
 	/* not found */
 	INTOFF;
-	ap = ckmalloc(sizeof (struct alias));
-	ap->name = savestr(name);
+	ap = ckmalloc(psh, sizeof (struct alias));
+	ap->name = savestr(psh, name);
 	/*
 	 * XXX - HACK: in order that the parser will not finish reading the
@@ -99,9 +99,9 @@
 	 */
 #ifdef notyet
-	ap->val = savestr(val);
+	ap->val = savestr(psh, val);
 #else /* hack */
 	{
 	size_t len = strlen(val);
-	ap->val = ckmalloc(len + 2);
+	ap->val = ckmalloc(psh, len + 2);
 	memcpy(ap->val, val, len);
 	ap->val[len] = ' ';	/* fluff */
@@ -135,7 +135,7 @@
 				INTOFF;
 				*app = ap->next;
-				ckfree(ap->name);
-				ckfree(ap->val);
-				ckfree(ap);
+				ckfree(psh, ap->name);
+				ckfree(psh, ap->val);
+				ckfree(psh, ap);
 				INTON;
 			}
@@ -166,9 +166,9 @@
 		psh->atab[i] = NULL;
 		while (ap) {
-			ckfree(ap->name);
-			ckfree(ap->val);
+			ckfree(psh, ap->name);
+			ckfree(psh, ap->val);
 			tmp = ap;
 			ap = ap->next;
-			ckfree(tmp);
+			ckfree(psh, tmp);
 		}
 	}
Index: /trunk/src/kash/cd.c
===================================================================
--- /trunk/src/kash/cd.c	(revision 2289)
+++ /trunk/src/kash/cd.c	(revision 2290)
@@ -253,5 +253,5 @@
 	if (dir == NULL || psh->curdir == NULL)  {
 		if (psh->prevdir)
-			ckfree(psh->prevdir);
+			ckfree(psh, psh->prevdir);
 		INTOFF;
 		psh->prevdir = psh->curdir;
@@ -289,7 +289,7 @@
 	INTOFF;
 	if (psh->prevdir)
-		ckfree(psh->prevdir);
+		ckfree(psh, psh->prevdir);
 	psh->prevdir = psh->curdir;
-	psh->curdir = savestr(stackblock(psh));
+	psh->curdir = savestr(psh, stackblock(psh));
 	setvar(psh, "PWD", psh->curdir, VEXPORT);
 	INTON;
@@ -352,5 +352,5 @@
 		    stdot.st_dev == stpwd.st_dev &&
 		    stdot.st_ino == stpwd.st_ino) {
-			psh->curdir = savestr(pwd);
+			psh->curdir = savestr(psh, pwd);
 			return psh->curdir;
 		}
@@ -385,5 +385,5 @@
 		pwd = stalloc(psh, i);
 		if (shfile_getcwd(&psh->fdtab, pwd, i) != NULL) {
-			psh->curdir = savestr(pwd);
+			psh->curdir = savestr(psh, pwd);
 			return;
 		}
Index: /trunk/src/kash/eval.c
===================================================================
--- /trunk/src/kash/eval.c	(revision 2289)
+++ /trunk/src/kash/eval.c	(revision 2290)
@@ -614,9 +614,9 @@
 	if (sys_path == NULL) {
 		if (sysctl(mib, 2, 0, &len, 0, 0) != -1 &&
-		    (sys_path = ckmalloc(len + 5)) != NULL &&
+		    (sys_path = ckmalloc(psh, len + 5)) != NULL &&
 		    sysctl(mib, 2, sys_path + 5, &len, 0, 0) != -1) {
 			memcpy(sys_path, "PATH=", 5);
 		} else {
-			ckfree(sys_path);
+			ckfree(psh, sys_path);
 			/* something to keep things happy */
 			sys_path = def_path;
@@ -935,8 +935,8 @@
 		if (setjmp(jmploc.loc)) {
 			if (psh->exception == EXSHELLPROC) {
-				freeparam((volatile struct shparam *)
+				freeparam(psh, (volatile struct shparam *)
 				    &saveparam);
 			} else {
-				freeparam(&psh->shellparam);
+				freeparam(psh, &psh->shellparam);
 				psh->shellparam = saveparam;
 			}
@@ -957,5 +957,5 @@
 		poplocalvars(psh);
 		psh->localvars = savelocalvars;
-		freeparam(&psh->shellparam);
+		freeparam(psh, &psh->shellparam);
 		psh->shellparam = saveparam;
 		psh->handler = savehandler;
Index: /trunk/src/kash/exec.c
===================================================================
--- /trunk/src/kash/exec.c	(revision 2289)
+++ /trunk/src/kash/exec.c	(revision 2290)
@@ -213,5 +213,5 @@
 		initshellproc(psh);
 		setinputfile(psh, cmd, 0);
-		psh->commandname = psh->arg0 = savestr(argv[0]);
+		psh->commandname = psh->arg0 = savestr(psh, argv[0]);
 #ifdef EXEC_HASH_BANG_SCRIPT
 		pgetc(psh); pungetc(psh);		/* fill up input buffer */
@@ -296,5 +296,5 @@
 		error(psh, "Bad #! line");
 	for (ap2 = argv ; *ap2++ != NULL ; );
-	new = ckmalloc(i + ((char *)ap2 - (char *)argv));
+	new = ckmalloc(psh, i + ((char *)ap2 - (char *)argv));
 	ap = newargs, ap2 = new;
 	while ((i -= sizeof (char **)) >= 0)
@@ -868,5 +868,5 @@
 			     psh->builtinloc >= firstchange)) {
 				*pp = cmdp->next;
-				ckfree(cmdp);
+				ckfree(psh, cmdp);
 			} else {
 				pp = &cmdp->next;
@@ -908,6 +908,6 @@
 			if (cmdp->cmdtype == CMDFUNCTION) {
 				*pp = cmdp->next;
-				freefunc(cmdp->param.func);
-				ckfree(cmdp);
+				freefunc(psh, cmdp->param.func);
+				ckfree(psh, cmdp);
 			} else {
 				pp = &cmdp->next;
@@ -952,5 +952,5 @@
 	if (add && cmdp == NULL) {
 		INTOFF;
-		cmdp = *pp = ckmalloc(sizeof (struct tblentry) - ARB
+		cmdp = *pp = ckmalloc(psh, sizeof (struct tblentry) - ARB
 					+ strlen(name) + 1);
 		cmdp->next = NULL;
@@ -976,5 +976,5 @@
 	cmdp = *lastcmdentry;
 	*lastcmdentry = cmdp->next;
-	ckfree(cmdp);
+	ckfree(psh, cmdp);
 	INTON;
 }
@@ -1013,5 +1013,5 @@
 	if (cmdp->cmdtype != CMDSPLBLTIN) {
 		if (cmdp->cmdtype == CMDFUNCTION) {
-			freefunc(cmdp->param.func);
+			freefunc(psh, cmdp->param.func);
 		}
 		cmdp->cmdtype = entry->cmdtype;
@@ -1027,5 +1027,5 @@
 
 void
-defun(shinstance *psh,char *name, union node *func)
+defun(shinstance *psh, char *name, union node *func)
 {
 	struct cmdentry entry;
@@ -1033,5 +1033,5 @@
 	INTOFF;
 	entry.cmdtype = CMDFUNCTION;
-	entry.u.func = copyfunc(func);
+	entry.u.func = copyfunc(psh, func);
 	addcmdentry(psh, name, &entry);
 	INTON;
@@ -1050,5 +1050,5 @@
 	if ((cmdp = cmdlookup(psh, name, 0)) != NULL &&
 	    cmdp->cmdtype == CMDFUNCTION) {
-		freefunc(cmdp->param.func);
+		freefunc(psh, cmdp->param.func);
 		delete_cmd_entry(psh);
 		return (0);
Index: /trunk/src/kash/expand.c
===================================================================
--- /trunk/src/kash/expand.c	(revision 2289)
+++ /trunk/src/kash/expand.c	(revision 2290)
@@ -309,5 +309,5 @@
 			INTOFF;
 			ifsp = psh->ifsfirst.next->next;
-			ckfree(psh->ifsfirst.next);
+			ckfree(psh, psh->ifsfirst.next);
 			psh->ifsfirst.next = ifsp;
 			INTON;
@@ -329,5 +329,5 @@
 		INTOFF;
 		ifsp = psh->ifslastp->next->next;
-		ckfree(psh->ifslastp->next);
+		ckfree(psh, psh->ifslastp->next);
 		psh->ifslastp->next = ifsp;
 		INTON;
@@ -463,5 +463,5 @@
 		shfile_close(&psh->fdtab, in.fd);
 	if (in.buf)
-		ckfree(in.buf);
+		ckfree(psh, in.buf);
 	if (in.jp)
 		psh->back_exitstatus = waitforjob(psh, in.jp);
@@ -922,5 +922,5 @@
 			return;
 		}
-		ifsp = (struct ifsregion *)ckmalloc(sizeof (struct ifsregion));
+		ifsp = (struct ifsregion *)ckmalloc(psh, sizeof (struct ifsregion));
 		psh->ifslastp->next = ifsp;
 	}
@@ -1045,5 +1045,5 @@
 		INTOFF;
 		ifsp = psh->ifsfirst.next->next;
-		ckfree(psh->ifsfirst.next);
+		ckfree(psh, psh->ifsfirst.next);
 		psh->ifsfirst.next = ifsp;
 		INTON;
@@ -1086,9 +1086,9 @@
 		if (psh->expdir == NULL) {
 			size_t i = strlen(str->text);
-			psh->expdir = ckmalloc(i < 2048 ? 2048 : i); /* XXX */
+			psh->expdir = ckmalloc(psh, i < 2048 ? 2048 : i); /* XXX */
 		}
 
 		expmeta(psh, psh->expdir, str->text);
-		ckfree(psh->expdir);
+		ckfree(psh, psh->expdir);
 		psh->expdir = NULL;
 		INTON;
Index: /trunk/src/kash/generated/init.c
===================================================================
--- /trunk/src/kash/generated/init.c	(revision 2289)
+++ /trunk/src/kash/generated/init.c	(revision 2290)
@@ -189,5 +189,5 @@
 	      psh->out2 = &psh->errout;
 	      if (psh->memout.buf != NULL) {
-		      ckfree(psh->memout.buf);
+		      ckfree(psh, psh->memout.buf);
 		      psh->memout.buf = NULL;
 	      }
Index: /trunk/src/kash/generated/nodes.c
===================================================================
--- /trunk/src/kash/generated/nodes.c	(revision 2289)
+++ /trunk/src/kash/generated/nodes.c	(revision 2290)
@@ -49,4 +49,5 @@
 #include "machdep.h"
 #include "mystring.h"
+#include "shinstance.h"
 
 
@@ -99,5 +100,6 @@
 
 union node *
-copyfunc(n)
+copyfunc(psh, n)
+    struct shinstance *psh;
 	union node *n;
 {
@@ -107,5 +109,5 @@
 	funcstringsize = 0;
 	calcsize(n);
-	funcblock = ckmalloc(funcblocksize + funcstringsize);
+	funcblock = ckmalloc(psh, funcblocksize + funcstringsize);
 	funcstring = (char *) funcblock + funcblocksize;
 	return copynode(n);
@@ -340,8 +342,9 @@
 
 void
-freefunc(n)
+freefunc(psh, n)
+    shinstance *psh;
 	union node *n;
 {
 	if (n)
-		ckfree(n);
-}
+		ckfree(psh, n);
+}
Index: /trunk/src/kash/generated/nodes.h
===================================================================
--- /trunk/src/kash/generated/nodes.h	(revision 2289)
+++ /trunk/src/kash/generated/nodes.h	(revision 2290)
@@ -156,4 +156,4 @@
 
 
-union node *copyfunc(union node *);
-void freefunc(union node *);
+union node *copyfunc(struct shinstance *, union node *);
+void freefunc(struct shinstance *, union node *);
Index: /trunk/src/kash/input.c
===================================================================
--- /trunk/src/kash/input.c	(revision 2289)
+++ /trunk/src/kash/input.c	(revision 2290)
@@ -343,5 +343,5 @@
 /*dprintf("*** calling pushstring: %s, %d\n", s, len);*/
 	if (psh->parsefile->strpush) {
-		sp = ckmalloc(sizeof (struct strpush));
+		sp = ckmalloc(psh, sizeof (struct strpush));
 		sp->prev = psh->parsefile->strpush;
 		psh->parsefile->strpush = sp;
@@ -373,5 +373,5 @@
 	psh->parsefile->strpush = sp->prev;
 	if (sp != &(psh->parsefile->basestrpush))
-		ckfree(sp);
+		ckfree(psh, sp);
 	INTON;
 }
@@ -415,5 +415,5 @@
 	if (push) {
 		pushfile(psh);
-		psh->parsefile->buf = ckmalloc(BUFSIZ);
+		psh->parsefile->buf = ckmalloc(psh, BUFSIZ);
 	}
 	if (psh->parsefile->fd > 0)
@@ -421,5 +421,5 @@
 	psh->parsefile->fd = fd;
 	if (psh->parsefile->buf == NULL)
-		psh->parsefile->buf = ckmalloc(BUFSIZ);
+		psh->parsefile->buf = ckmalloc(psh, BUFSIZ);
 	psh->parselleft = psh->parsenleft = 0;
 	psh->plinno = 1;
@@ -460,5 +460,5 @@
 	psh->parsefile->nextc = psh->parsenextc;
 	psh->parsefile->linno = psh->plinno;
-	pf = (struct parsefile *)ckmalloc(sizeof (struct parsefile));
+	pf = (struct parsefile *)ckmalloc(psh, sizeof (struct parsefile));
 	pf->prev = psh->parsefile;
 	pf->fd = -1;
@@ -478,9 +478,9 @@
 		shfile_close(&psh->fdtab, pf->fd);
 	if (pf->buf)
-		ckfree(pf->buf);
+		ckfree(psh, pf->buf);
 	while (pf->strpush)
 		popstring(psh);
 	psh->parsefile = pf->prev;
-	ckfree(pf);
+	ckfree(psh, pf);
 	psh->parsenleft = psh->parsefile->nleft;
 	psh->parselleft = psh->parsefile->lleft;
Index: /trunk/src/kash/jobs.c
===================================================================
--- /trunk/src/kash/jobs.c	(revision 2289)
+++ /trunk/src/kash/jobs.c	(revision 2290)
@@ -519,5 +519,5 @@
 	INTOFF;
 	if (jp->ps != &jp->ps0) {
-		ckfree(jp->ps);
+		ckfree(psh, jp->ps);
 		jp->ps = &jp->ps0;
 	}
@@ -723,7 +723,7 @@
 			INTOFF;
 			if (psh->njobs == 0) {
-				psh->jobtab = ckmalloc(4 * sizeof psh->jobtab[0]);
+				psh->jobtab = ckmalloc(psh, 4 * sizeof psh->jobtab[0]);
 			} else {
-				jp = ckmalloc((psh->njobs + 4) * sizeof psh->jobtab[0]);
+				jp = ckmalloc(psh, (psh->njobs + 4) * sizeof psh->jobtab[0]);
 				memcpy(jp, psh->jobtab, psh->njobs * sizeof jp[0]);
 				/* Relocate `ps' pointers */
@@ -731,5 +731,5 @@
 					if (jp[i].ps == &psh->jobtab[i].ps0)
 						jp[i].ps = &jp[i].ps0;
-				ckfree(psh->jobtab);
+				ckfree(psh, psh->jobtab);
 				psh->jobtab = jp;
 			}
@@ -752,5 +752,5 @@
 #endif
 	if (nprocs > 1) {
-		jp->ps = ckmalloc(nprocs * sizeof (struct procstat));
+		jp->ps = ckmalloc(psh, nprocs * sizeof (struct procstat));
 	} else {
 		jp->ps = &jp->ps0;
Index: /trunk/src/kash/memalloc.c
===================================================================
--- /trunk/src/kash/memalloc.c	(revision 2289)
+++ /trunk/src/kash/memalloc.c	(revision 2290)
@@ -56,11 +56,11 @@
 
 pointer
-ckmalloc(size_t nbytes)
+ckmalloc(shinstance *psh, size_t nbytes)
 {
 	pointer p;
 
-	p = malloc(nbytes);
+	p = sh_malloc(psh, nbytes);
 	if (p == NULL)
-		error(NULL, "Out of space");
+		error(psh, "Out of space");
 	return p;
 }
@@ -72,9 +72,9 @@
 
 pointer
-ckrealloc(pointer p, size_t nbytes)
-{
-	p = realloc(p, nbytes);
+ckrealloc(struct shinstance *psh, pointer p, size_t nbytes)
+{
+	p = sh_realloc(psh, p, nbytes);
 	if (p == NULL)
-		error(NULL, "Out of space");
+		error(psh, "Out of space");
 	return p;
 }
@@ -86,10 +86,11 @@
 
 char *
-savestr(const char *s)
+savestr(struct shinstance *psh, const char *s)
 {
 	char *p;
-
-	p = ckmalloc(strlen(s) + 1);
-	scopy(s, p);
+    size_t len = strlen(s);
+
+	p = ckmalloc(psh, len + 1);
+	memcpy(p, s, len + 1);
 	return p;
 }
@@ -134,5 +135,5 @@
 			blocksize = MINSIZE;
 		INTOFF;
-		sp = ckmalloc(sizeof(struct stack_block) - MINSIZE + blocksize);
+		sp = ckmalloc(psh, sizeof(struct stack_block) - MINSIZE + blocksize);
 		sp->prev = psh->stackp;
 		psh->stacknxt = sp->space;
@@ -182,5 +183,5 @@
 		sp = psh->stackp;
 		psh->stackp = sp->prev;
-		ckfree(sp);
+		ckfree(psh, sp);
 	}
 	psh->stacknxt = mark->stacknxt;
@@ -214,5 +215,5 @@
 		sp = psh->stackp;
 		psh->stackp = sp->prev;
-		sp = ckrealloc((pointer)sp,
+		sp = ckrealloc(psh, (pointer)sp,
 		    sizeof(struct stack_block) - MINSIZE + newlen);
 		sp->prev = psh->stackp;
Index: /trunk/src/kash/memalloc.h
===================================================================
--- /trunk/src/kash/memalloc.h	(revision 2289)
+++ /trunk/src/kash/memalloc.h	(revision 2290)
@@ -48,7 +48,7 @@
 extern int herefd;*/
 
-pointer ckmalloc(size_t);
-pointer ckrealloc(pointer, size_t);
-char *savestr(const char *);
+pointer ckmalloc(struct shinstance *, size_t);
+pointer ckrealloc(struct shinstance *, pointer, size_t);
+char *savestr(struct shinstance *, const char *);
 pointer stalloc(struct shinstance *, size_t);
 void stunalloc(struct shinstance *, pointer);
@@ -75,3 +75,3 @@
 #define grabstackstr(psh, p)        stalloc((psh), stackblocksize(psh) - (psh)->sstrnleft)
 
-#define ckfree(p)	free((pointer)(p))
+#define ckfree(psh, p)	            sh_free(psh, (pointer)(p))
Index: /trunk/src/kash/miscbltin.c
===================================================================
--- /trunk/src/kash/miscbltin.c	(revision 2289)
+++ /trunk/src/kash/miscbltin.c	(revision 2290)
@@ -59,4 +59,5 @@
 #include "mystring.h"
 #include "shinstance.h"
+#include "shfile.h"
 
 #undef rflag
@@ -220,8 +221,5 @@
 	}
 
-	INTOFF;
-	mask = umask(0);
-	umask(mask);
-	INTON;
+	mask = shfile_get_umask(&psh->fdtab);
 
 	if ((ap = *psh->argptr) == NULL) {
@@ -268,5 +266,5 @@
 				mask = (mask << 3) + (*ap - '0');
 			} while (*++ap != '\0');
-			umask(mask);
+			shfile_set_umask(&psh->fdtab, mask);
 		} else {
 			void *set;
@@ -275,5 +273,5 @@
 			if ((set = bsd_setmode(psh, ap)) != 0) {
 				mask = bsd_getmode(set, ~mask & 0777);
-				ckfree(set);
+				ckfree(psh, set);
 			}
 			INTON;
@@ -281,5 +279,5 @@
 				error(psh, "Illegal mode: %s", ap);
 
-			umask(~mask & 0777);
+			shfile_set_umask(&psh->fdtab, ~mask & 0777);
 		}
 	}
Index: /trunk/src/kash/nodes.c.pat
===================================================================
--- /trunk/src/kash/nodes.c.pat	(revision 2289)
+++ /trunk/src/kash/nodes.c.pat	(revision 2290)
@@ -45,4 +45,5 @@
 #include "machdep.h"
 #include "mystring.h"
+#include "shinstance.h"
 
 
@@ -68,5 +69,6 @@
 
 union node *
-copyfunc(n)
+copyfunc(psh, n)
+    struct shinstance *psh;
 	union node *n;
 {
@@ -76,5 +78,5 @@
 	funcstringsize = 0;
 	calcsize(n);
-	funcblock = ckmalloc(funcblocksize + funcstringsize);
+	funcblock = ckmalloc(psh, funcblocksize + funcstringsize);
 	funcstring = (char *) funcblock + funcblocksize;
 	return copynode(n);
@@ -159,8 +161,9 @@
 
 void
-freefunc(n)
+freefunc(psh, n)
+        shinstance *psh;
 	union node *n;
 {
 	if (n)
-		ckfree(n);
+		ckfree(psh, n);
 }
Index: /trunk/src/kash/options.c
===================================================================
--- /trunk/src/kash/options.c	(revision 2289)
+++ /trunk/src/kash/options.c	(revision 2290)
@@ -280,10 +280,10 @@
 	for (nparam = 0 ; argv[nparam] ; nparam++)
 		continue;
-	ap = newparam = ckmalloc((nparam + 1) * sizeof *ap);
+	ap = newparam = ckmalloc(psh, (nparam + 1) * sizeof *ap);
 	while (*argv) {
-		*ap++ = savestr(*argv++);
+		*ap++ = savestr(psh, *argv++);
 	}
 	*ap = NULL;
-	freeparam(&psh->shellparam);
+	freeparam(psh, &psh->shellparam);
 	psh->shellparam.malloc = 1;
 	psh->shellparam.nparam = nparam;
@@ -298,5 +298,5 @@
 
 void
-freeparam(volatile struct shparam *param)
+freeparam(shinstance *psh, volatile struct shparam *param)
 {
 	char **ap;
@@ -304,6 +304,6 @@
 	if (param->malloc) {
 		for (ap = param->p ; *ap ; ap++)
-			ckfree(*ap);
-		ckfree(param->p);
+			ckfree(psh, *ap);
+		ckfree(psh, param->p);
 	}
 }
@@ -330,5 +330,5 @@
 	for (ap1 = psh->shellparam.p ; --n >= 0 ; ap1++) {
 		if (psh->shellparam.malloc)
-			ckfree(*ap1);
+			ckfree(psh, *ap1);
 	}
 	ap2 = psh->shellparam.p;
Index: /trunk/src/kash/options.h
===================================================================
--- /trunk/src/kash/options.h	(revision 2289)
+++ /trunk/src/kash/options.h	(revision 2290)
@@ -133,5 +133,5 @@
 void optschanged(struct shinstance *);
 void setparam(struct shinstance *, char **);
-void freeparam(volatile struct shparam *);
+void freeparam(struct shinstance *, volatile struct shparam *);
 int shiftcmd(struct shinstance *, int, char **);
 int setcmd(struct shinstance *, int, char **);
Index: /trunk/src/kash/output.c
===================================================================
--- /trunk/src/kash/output.c	(revision 2289)
+++ /trunk/src/kash/output.c	(revision 2290)
@@ -89,5 +89,5 @@
 	psh->out2 = &psh->errout;
 	if (psh->memout.buf != NULL) {
-		ckfree(psh->memout.buf);
+		ckfree(psh, psh->memout.buf);
 		psh->memout.buf = NULL;
 	}
@@ -153,5 +153,5 @@
 	} else if (dest->buf == NULL) {
 		INTOFF;
-		dest->buf = ckmalloc(dest->bufsize);
+		dest->buf = ckmalloc(psh, dest->bufsize);
 		dest->nextc = dest->buf;
 		dest->nleft = dest->bufsize;
@@ -161,5 +161,5 @@
 		INTOFF;
 		dest->bufsize <<= 1;
-		dest->buf = ckrealloc(dest->buf, dest->bufsize);
+		dest->buf = ckrealloc(psh, dest->buf, dest->bufsize);
 		dest->nleft = dest->bufsize - offset;
 		dest->nextc = dest->buf + offset;
@@ -198,5 +198,5 @@
 	INTOFF;
 	if (psh->output.buf) {
-		ckfree(psh->output.buf);
+		ckfree(psh, psh->output.buf);
 		psh->output.buf = NULL;
 		psh->output.nleft = 0;
Index: /trunk/src/kash/parser.c
===================================================================
--- /trunk/src/kash/parser.c	(revision 2289)
+++ /trunk/src/kash/parser.c	(revision 2290)
@@ -1151,5 +1151,5 @@
 	psh->wordtext = out;
 	if (dblquotep != NULL)
-	    ckfree(dblquotep);
+	    ckfree(psh, dblquotep);
 	return psh->lasttoken = TWORD;
 /* end of readtoken routine */
@@ -1347,5 +1347,5 @@
 			varnest++;
 			if (varnest >= maxnest) {
-				dblquotep = ckrealloc(dblquotep, maxnest / 8);
+				dblquotep = ckrealloc(psh, dblquotep, maxnest / 8);
 				dblquotep[(maxnest / 32) - 1] = 0;
 				maxnest += 32;
@@ -1380,5 +1380,5 @@
 	if (setjmp(jmploc.loc)) {
 		if (str)
-			ckfree(str);
+			ckfree(psh, str);
 		psh->parsebackquote = 0;
 		psh->handler = savehandler;
@@ -1389,5 +1389,5 @@
 	savelen = (int)(out - stackblock(psh));
 	if (savelen > 0) {
-		str = ckmalloc(savelen);
+		str = ckmalloc(psh, savelen);
 		memcpy(str, stackblock(psh), savelen);
 	}
@@ -1495,5 +1495,5 @@
 		STADJUST(psh, savelen, out);
 		INTOFF;
-		ckfree(str);
+		ckfree(psh, str);
 		str = NULL;
 		INTON;
Index: /trunk/src/kash/redir.c
===================================================================
--- /trunk/src/kash/redir.c	(revision 2289)
+++ /trunk/src/kash/redir.c	(revision 2290)
@@ -117,5 +117,5 @@
 		 * flags & REDIR_PUSH is never true if REDIR_VFORK is set.
 		 */
-		sv = ckmalloc(sizeof (struct redirtab));
+		sv = ckmalloc(psh, sizeof (struct redirtab));
 		for (i = 0 ; i < 10 ; i++)
 			sv->renamed[i] = EMPTY;
@@ -311,5 +311,5 @@
 	INTOFF;
 	psh->redirlist = rp->next;
-	ckfree(rp);
+	ckfree(psh, rp);
 	INTON;
 }
Index: /trunk/src/kash/setmode.c
===================================================================
--- /trunk/src/kash/setmode.c	(revision 2289)
+++ /trunk/src/kash/setmode.c	(revision 2290)
@@ -167,7 +167,7 @@
 		BITCMD *newset;						\
 		setlen += SET_LEN_INCR;					\
-		newset = realloc(saveset, sizeof(BITCMD) * setlen);	\
+		newset = sh_realloc(NULL, saveset, sizeof(BITCMD) * setlen);	\
 		if (newset == NULL) {					\
-			free(saveset);					\
+			sh_free(NULL, saveset);					\
 			return (NULL);					\
 		}							\
@@ -202,5 +202,5 @@
 	setlen = SET_LEN + 2;
 
-	if ((set = malloc(sizeof(BITCMD) * setlen)) == NULL)
+	if ((set = sh_malloc(NULL, sizeof(BITCMD) * setlen)) == NULL)
 		return (NULL);
 	saveset = set;
@@ -214,5 +214,5 @@
 		perm = (mode_t)strtol(p, &ep, 8);
 		if (*ep || perm & ~(STANDARD_BITS|S_ISTXT)) {
-			free(saveset);
+			sh_free(NULL, saveset);
 			return (NULL);
 		}
@@ -248,5 +248,5 @@
 
 getop:		if ((op = *p++) != '+' && op != '-' && op != '=') {
-			free(saveset);
+			sh_free(NULL, saveset);
 			return (NULL);
 		}
Index: /trunk/src/kash/shfile.c
===================================================================
--- /trunk/src/kash/shfile.c	(revision 2289)
+++ /trunk/src/kash/shfile.c	(revision 2290)
@@ -150,5 +150,5 @@
         while (new_size < fdMin)
             new_size += SHFILE_GROW;
-        new_tab = realloc(pfdtab->tab, new_size * sizeof(shfile));
+        new_tab = sh_realloc(NULL, pfdtab->tab, new_size * sizeof(shfile));
         if (new_tab)
         {
@@ -230,5 +230,4 @@
 }
 
-
 /**
  * Constructs a path from the current directory and the passed in path.
@@ -257,5 +256,5 @@
 #if K_OS == K_OS_WINDOWS || K_OS == K_OS_OS2
         ||  *path == '\\'
-        ||  (   !*path
+        ||  (   *path
              && path[1] == ':'
              && (   (*path >= 'A' && *path <= 'Z')
@@ -1050,4 +1049,9 @@
 }
 
+void shfile_set_umask(shfdtab *pfdtab, mode_t mask)
+{
+    (void)mask;
+}
+
 
 shdir *shfile_opendir(shfdtab *pfdtab, const char *dir)
Index: /trunk/src/kash/shfile.h
===================================================================
--- /trunk/src/kash/shfile.h	(revision 2289)
+++ /trunk/src/kash/shfile.h	(revision 2290)
@@ -150,4 +150,5 @@
 #endif
 mode_t shfile_get_umask(shfdtab *);
+void   shfile_set_umask(shfdtab *, mode_t);
 
 
Index: /trunk/src/kash/shinstance.c
===================================================================
--- /trunk/src/kash/shinstance.c	(revision 2289)
+++ /trunk/src/kash/shinstance.c	(revision 2290)
@@ -169,5 +169,5 @@
 {
     memset(psh, 0, sizeof(*psh));
-    free(psh);
+    sh_free(NULL, psh);
 }
 
@@ -190,5 +190,5 @@
 
    /* alloc clone array. */
-   *dstp = dst = malloc(sizeof(*dst) * items + 1);
+   *dstp = dst = sh_malloc(NULL, sizeof(*dst) * items + 1);
    if (!dst)
        return -1;
@@ -198,11 +198,11 @@
    while (items-- > 0)
    {
-       dst[items] = strdup(src[items]);
+       dst[items] = sh_strdup(NULL, src[items]);
        if (!dst[items])
        {
            /* allocation error, clean up. */
            while (dst[++items])
-               free(dst[items]);
-           free(dst);
+               sh_free(NULL, dst[items]);
+           sh_free(NULL, dst);
            errno = ENOMEM;
            return -1;
@@ -231,5 +231,5 @@
      * The allocations.
      */
-    psh = calloc(sizeof(*psh), 1);
+    psh = sh_calloc(NULL, sizeof(*psh), 1);
     if (psh)
     {
@@ -344,4 +344,42 @@
 
     return ret;
+}
+
+/** malloc() */
+void *sh_malloc(shinstance *psh, size_t size)
+{
+    (void)psh;
+    return malloc(size);
+}
+
+/** calloc() */
+void *sh_calloc(shinstance *psh, size_t num, size_t size)
+{
+    (void)psh;
+    return calloc(num, size);
+}
+
+/** realloc() */
+void *sh_realloc(shinstance *psh, void *old, size_t new_size)
+{
+    return realloc(old, new_size);
+}
+
+/** strdup() */
+char *sh_strdup(shinstance *psh, const char *string)
+{
+    size_t len = strlen(string);
+    char *ret = sh_malloc(psh, len + 1);
+    if (ret)
+        memcpy(ret, string, len + 1);
+    return ret;
+}
+
+/** free() */
+void sh_free(shinstance *psh, void *ptr)
+{
+    if (ptr)
+        free(ptr);
+    (void)psh;
 }
 
Index: /trunk/src/kash/shinstance.h
===================================================================
--- /trunk/src/kash/shinstance.h	(revision 2289)
+++ /trunk/src/kash/shinstance.h	(revision 2290)
@@ -335,4 +335,11 @@
 char **sh_environ(shinstance *);
 const char *sh_gethomedir(shinstance *, const char *);
+
+/* heap */
+void *sh_malloc(shinstance *, size_t);
+void *sh_calloc(shinstance *, size_t, size_t);
+void *sh_realloc(shinstance *, void *, size_t);
+char *sh_strdup(shinstance *, const char *);
+void  sh_free(shinstance *, void *);
 
 /* signals */
Index: /trunk/src/kash/tests/trap-exit-1
===================================================================
--- /trunk/src/kash/tests/trap-exit-1	(revision 2289)
+++ /trunk/src/kash/tests/trap-exit-1	(revision 2290)
@@ -1,4 +1,3 @@
 #!/bin/sh
-set -x
 
 trap 'echo "trap-exit-1: overriding exit 1"; exit 0' EXIT
Index: /trunk/src/kash/trap.c
===================================================================
--- /trunk/src/kash/trap.c	(revision 2289)
+++ /trunk/src/kash/trap.c	(revision 2290)
@@ -192,8 +192,8 @@
 		INTOFF;
 		if (action)
-			action = savestr(action);
+			action = savestr(psh, action);
 
 		if (psh->trap[signo])
-			ckfree(psh->trap[signo]);
+			ckfree(psh, psh->trap[signo]);
 
 		psh->trap[signo] = action;
@@ -224,5 +224,5 @@
 			INTOFF;
 			if (!vforked) {
-				ckfree(*tp);
+				ckfree(psh, *tp);
 				*tp = NULL;
 			}
Index: /trunk/src/kash/var.c
===================================================================
--- /trunk/src/kash/var.c	(revision 2289)
+++ /trunk/src/kash/var.c	(revision 2290)
@@ -209,5 +209,5 @@
 	struct var **vpp;
 #ifdef PC_OS2_LIBPATHS
-	char *psz = ckmalloc(2048);
+	char *psz = ckmalloc(psh, 2048);
 	int rc;
 	int i;
@@ -232,5 +232,5 @@
 			int cch1 = strlen(libpath_envs[i]);
 			int cch2 = strlen(psz) + 1;
-			psh->libpath_vars[i].text = ckmalloc(cch1 + cch2);
+			psh->libpath_vars[i].text = ckmalloc(psh, cch1 + cch2);
 			memcpy(psh->libpath_vars[i].text, libpath_envs[i], cch1);
 			memcpy(psh->libpath_vars[i].text + cch1, psz, cch2);
@@ -246,5 +246,5 @@
 		*vpp = &psh->libpath_vars[i];
 	}
-	free(psz);
+	ckfree(psh, psz);
 #endif
 
@@ -332,5 +332,5 @@
 		len += strlen(val);
 	}
-	d = nameeq = ckmalloc(len);
+	d = nameeq = ckmalloc(psh, len);
 	q = name;
 	while (--namelen >= 0)
@@ -372,5 +372,5 @@
 
 		if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
-			ckfree(vp->text);
+			ckfree(psh, vp->text);
 
 		vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET);
@@ -394,5 +394,5 @@
 	if (flags & VNOSET)
 		return;
-	vp = ckmalloc(sizeof (*vp));
+	vp = ckmalloc(psh, sizeof (*vp));
 	vp->flags = flags & ~VNOFUNC;
 	vp->text = s;
@@ -416,5 +416,5 @@
 	INTOFF;
 	for (lp = list ; lp ; lp = lp->next) {
-		setvareq(psh, savestr(lp->text), flags);
+		setvareq(psh, savestr(psh, lp->text), flags);
 	}
 	INTON;
@@ -539,10 +539,10 @@
 				*prev = vp->next;
 				if ((vp->flags & VTEXTFIXED) == 0)
-					ckfree(vp->text);
+					ckfree(psh, vp->text);
 				if ((vp->flags & VSTRFIXED) == 0)
-					ckfree(vp);
+					ckfree(psh, vp);
 			} else {
 				if (vp->flags & VSTACK) {
-					vp->text = savestr(vp->text);
+					vp->text = savestr(psh, vp->text);
 					vp->flags &=~ VSTACK;
 				}
@@ -618,5 +618,5 @@
 	if (!list) {
 		list_len = 32;
-		list = ckmalloc(list_len * sizeof(*list));
+		list = ckmalloc(psh, list_len * sizeof(*list));
 	}
 
@@ -628,5 +628,5 @@
 				continue;
 			if (count >= list_len) {
-				list = ckrealloc(list,
+				list = ckrealloc(psh, list,
 					(list_len << 1) * sizeof(*list));
 				list_len <<= 1;
@@ -723,8 +723,8 @@
 
 	INTOFF;
-	lvp = ckmalloc(sizeof (struct localvar));
+	lvp = ckmalloc(psh, sizeof (struct localvar));
 	if (name[0] == '-' && name[1] == '\0') {
 		char *p;
-		p = ckmalloc(sizeof_optlist);
+		p = ckmalloc(psh, sizeof_optlist);
 		lvp->text = memcpy(p, psh->optlist, sizeof_optlist);
 		vp = NULL;
@@ -733,5 +733,5 @@
 		if (vp == NULL) {
 			if (strchr(name, '='))
-				setvareq(psh, savestr(name), VSTRFIXED|flags);
+				setvareq(psh, savestr(psh, name), VSTRFIXED|flags);
 			else
 				setvar(psh, name, NULL, VSTRFIXED|flags);
@@ -744,5 +744,5 @@
 			vp->flags |= VSTRFIXED|VTEXTFIXED;
 			if (name[vp->name_len] == '=')
-				setvareq(psh, savestr(name), flags);
+				setvareq(psh, savestr(psh, name), flags);
 		}
 	}
@@ -770,5 +770,5 @@
 		if (vp == NULL) {	/* $- saved */
 			memcpy(psh->optlist, lvp->text, sizeof_optlist);
-			ckfree(lvp->text);
+			ckfree(psh, lvp->text);
 		} else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) {
 			(void)unsetvar(psh, vp->text, 0);
@@ -777,9 +777,9 @@
 				(*vp->func)(psh, lvp->text + vp->name_len + 1);
 			if ((vp->flags & VTEXTFIXED) == 0)
-				ckfree(vp->text);
+				ckfree(psh, vp->text);
 			vp->flags = lvp->flags;
 			vp->text = lvp->text;
 		}
-		ckfree(lvp);
+		ckfree(psh, lvp);
 	}
 }
@@ -860,7 +860,7 @@
 		if ((vp->flags & VSTRFIXED) == 0) {
 			if ((vp->flags & VTEXTFIXED) == 0)
-				ckfree(vp->text);
+				ckfree(psh, vp->text);
 			*vpp = vp->next;
-			ckfree(vp);
+			ckfree(psh, vp);
 		}
 	}
