Blob Blame Raw
diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.orig ksh-20120801/src/cmd/ksh93/sh/subshell.c
--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.orig	2014-08-23 20:20:24.676186573 -0300
+++ ksh-20120801/src/cmd/ksh93/sh/subshell.c	2014-08-23 20:29:00.772151283 -0300
@@ -481,12 +481,12 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
 {
 	struct subshell sub_data;
 	register struct subshell *sp = &sub_data;
-	int jmpval,nsig=0,duped=0;
+	int jmpval,isig,nsig=0,duped=0;
 	long savecurenv = shp->curenv;
 	int savejobpgid = job.curpgid;
 	int *saveexitval = job.exitval;
 	int16_t subshell;
-	char *savsig;
+	char **savsig;
 	Sfio_t *iop=0;
 	struct checkpt buff;
 	struct sh_scoped savst;
@@ -561,10 +561,13 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
 		/* save trap table */
 		shp->st.otrapcom = 0;
 		shp->st.otrap = savst.trap;
-		if((nsig=shp->st.trapmax*sizeof(char*))>0 || shp->st.trapcom[0])
+		if((nsig=shp->st.trapmax)>0 || shp->st.trapcom[0])
 		{
-			nsig += sizeof(char*);
-			memcpy(savsig=malloc(nsig),(char*)&shp->st.trapcom[0],nsig);
+			++nsig;
+			savsig = malloc(nsig * sizeof(char*));
+			/* contents of shp->st.st.trapcom may change */
+			for (isig = 0; isig < nsig; ++isig)
+				savsig[isig] = shp->st.trapcom[isig] ? strdup(shp->st.trapcom[isig]) : NULL;
 			/* this nonsense needed for $(trap) */
 			shp->st.otrapcom = (char**)savsig;
 		}
@@ -729,7 +732,10 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
 		shp->st.otrap = 0;
 		if(nsig)
 		{
-			memcpy((char*)&shp->st.trapcom[0],savsig,nsig);
+			for (isig = 0; isig < nsig; ++isig)
+				if (shp->st.trapcom[isig])
+					free(shp->st.trapcom[isig]);
+			memcpy((char*)&shp->st.trapcom[0],savsig,nsig*sizeof(char*));
 			free((void*)savsig);
 		}
 		shp->options = sp->options;