summaryrefslogtreecommitdiffstats
path: root/source/ap/ksh93/patches
diff options
context:
space:
mode:
Diffstat (limited to 'source/ap/ksh93/patches')
-rw-r--r--source/ap/ksh93/patches/ksh-20070328-builtins.patch31
-rw-r--r--source/ap/ksh93/patches/ksh-20080202-manfix.patch47
-rw-r--r--source/ap/ksh93/patches/ksh-20100202-pathvar.patch20
-rw-r--r--source/ap/ksh93/patches/ksh-20100621-fdstatus.patch54
-rw-r--r--source/ap/ksh93/patches/ksh-20100621-manfix3.patch12
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-alarmifs.patch33
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-argvfix.patch13
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-assoc-unset-leak.patch20
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-cdfix3.patch12
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-cdfork.patch40
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-covsfix.patch58
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-crash.patch64
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-diskfull.patch20
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-emptyarrayinit.patch11
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-fd2lost.patch64
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-filecomsubst.patch11
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-forkbomb.patch12
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-fununset.patch12
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-heresub.patch32
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-kshmfix.patch66
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-lexfix.patch56
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-locking.patch26
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-macro.patch205
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-manfix4.patch12
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-memlik.patch37
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-memlik3.patch76
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-mlikfiks.patch34
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-mtty.patch12
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-noexeccdfix.patch40
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-nohupfork.patch11
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-nomulti.patch11
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-oldenvinit.patch95
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-retfix.patch20
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-rmdirfix.patch (renamed from source/ap/ksh93/patches/rmdirfix.patch)2
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-roundit.patch12
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-sufix.patch11
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-tpstl.patch12
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-trapcom.patch47
-rw-r--r--source/ap/ksh93/patches/ksh-20120801-xufix.patch29
-rw-r--r--source/ap/ksh93/patches/ksh-20130613-cdfix4.patch15
-rw-r--r--source/ap/ksh93/patches/ksh-20130628-longer.patch58
-rw-r--r--source/ap/ksh93/patches/ksh-20140301-fikspand.patch12
-rw-r--r--source/ap/ksh93/patches/ksh-20140415-hokaido.patch37
-rw-r--r--source/ap/ksh93/patches/ksh-20140801-arraylen.patch11
-rw-r--r--source/ap/ksh93/patches/ksh-20140929-safefd.patch52
45 files changed, 1538 insertions, 27 deletions
diff --git a/source/ap/ksh93/patches/ksh-20070328-builtins.patch b/source/ap/ksh93/patches/ksh-20070328-builtins.patch
index 5c6b21c2f..061bf9aa0 100644
--- a/source/ap/ksh93/patches/ksh-20070328-builtins.patch
+++ b/source/ap/ksh93/patches/ksh-20070328-builtins.patch
@@ -1,32 +1,11 @@
-diff -up ksh-20120620/src/cmd/ksh93/data/builtins.c.builtins ksh-20120620/src/cmd/ksh93/data/builtins.c
---- ksh-20120620/src/cmd/ksh93/data/builtins.c.builtins 2012-06-19 10:02:12.000000000 +0200
-+++ ksh-20120620/src/cmd/ksh93/data/builtins.c 2012-06-22 12:35:05.587717588 +0200
-@@ -131,20 +131,28 @@ const struct shtable3 shtab_builtins[] =
- #undef mktemp /* undo possible map-libc mktemp => _ast_mktemp */
- #include SHOPT_CMDLIB_HDR
- #else
-+#if 1
- CMDLIST(basename)
- CMDLIST(chmod)
+diff -up ksh-20080202/src/cmd/ksh93/data/builtins.c.builtins ksh-20080202/src/cmd/ksh93/data/builtins.c
+--- ksh-20080202/src/cmd/ksh93/data/builtins.c.builtins 2008-10-01 09:24:46.000000000 +0200
++++ ksh-20080202/src/cmd/ksh93/data/builtins.c 2008-10-01 09:24:58.000000000 +0200
+@@ -129,7 +129,6 @@ const struct shtable3 shtab_builtins[] =
CMDLIST(dirname)
CMDLIST(getconf)
CMDLIST(head)
-+#if 0
-+does not work when ACLs are used
- CMDLIST(mkdir)
-+#endif
+- CMDLIST(mkdir)
CMDLIST(logname)
-+#if 1
-+//does not work in chrooted environments, because /dev/fd/? is missing
CMDLIST(cat)
-+#endif
CMDLIST(cmp)
- CMDLIST(cut)
- CMDLIST(uname)
- CMDLIST(wc)
- CMDLIST(sync)
- #endif
-+#endif
- #if SHOPT_REGRESS
- "__regress__", NV_BLTIN|BLT_ENV, bltin(__regress__),
- #endif
diff --git a/source/ap/ksh93/patches/ksh-20080202-manfix.patch b/source/ap/ksh93/patches/ksh-20080202-manfix.patch
new file mode 100644
index 000000000..8fe422572
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20080202-manfix.patch
@@ -0,0 +1,47 @@
+diff -up ksh-20120801/src/cmd/ksh93/sh.1.manfix ksh-20120801/src/cmd/ksh93/sh.1
+--- ksh-20120801/src/cmd/ksh93/sh.1.manfix 2012-06-18 16:16:22.000000000 +0200
++++ ksh-20120801/src/cmd/ksh93/sh.1 2013-04-30 13:35:17.393909479 +0200
+@@ -39,7 +39,7 @@ ksh93, rksh93, pfksh93 \- KornShell, a s
+ .B ksh93
+ .\}
+ [
+-.B \(+-abcefhikmnoprstuvxBCDP
++.B \(+-abcefhiknoprstuvxBCDP
+ ] [
+ .B \-R
+ file ] [
+@@ -47,25 +47,6 @@ file ] [
+ option ] .\|.\|. [
+ .B \-
+ ] [ arg .\|.\|. ]
+-.br
+-.if \nZ=0 \{\
+-.B rsh
+-.\}
+-.if \nZ=1 \{\
+-.B rksh
+-.\}
+-.if \nZ=2 \{\
+-.B rksh93
+-.\}
+-[
+-.B \(+-abcefhikmnoprstuvxBCD
+-] [
+-.B \-R
+-file ] [
+-.B \(+-o
+-option ] .\|.\|. [
+-.B \-
+-] [ arg .\|.\|. ]
+ .SH DESCRIPTION
+ .if \nZ=0 .I Sh\^
+ .if \nZ=1 .I Ksh\^
+@@ -7963,6 +7944,8 @@ option is used
+ to generate a cross reference database
+ that can be used by a separate utility
+ to find definitions and references for variables and commands.
++The filename argument specifies the generated database. A script file must be
++provided on the command line as well.
+ .PP
+ The remaining options and arguments are described under the
+ .B set
diff --git a/source/ap/ksh93/patches/ksh-20100202-pathvar.patch b/source/ap/ksh93/patches/ksh-20100202-pathvar.patch
new file mode 100644
index 000000000..508649962
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20100202-pathvar.patch
@@ -0,0 +1,20 @@
+diff -up ksh-20100202/src/cmd/ksh93/sh.1.pathvar ksh-20100202/src/cmd/ksh93/sh.1
+--- ksh-20100202/src/cmd/ksh93/sh.1.pathvar 2011-04-26 16:42:08.000000000 +0200
++++ ksh-20100202/src/cmd/ksh93/sh.1 2011-04-27 09:09:00.315883280 +0200
+@@ -4025,13 +4025,9 @@ the directory containing the command.
+ Alternative directory names are separated by
+ a colon
+ .RB ( : ).
+-The default path is
+-.B /bin:/usr/bin:
+-(specifying
+-.BR /bin ,
+-.BR /usr/bin ,
+-and the current directory
+-in that order).
++The default path is equal to
++.BI getconf\ PATH
++output.
+ The current directory can be specified by
+ two or more adjacent colons, or by a colon
+ at the beginning or end of the path list.
diff --git a/source/ap/ksh93/patches/ksh-20100621-fdstatus.patch b/source/ap/ksh93/patches/ksh-20100621-fdstatus.patch
new file mode 100644
index 000000000..99abb5533
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20100621-fdstatus.patch
@@ -0,0 +1,54 @@
+diff -up ksh-20120801/src/cmd/ksh93/sh/io.c.fdstatus ksh-20120801/src/cmd/ksh93/sh/io.c
+--- ksh-20120801/src/cmd/ksh93/sh/io.c.fdstatus 2013-07-04 18:01:27.187516655 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/io.c 2013-07-04 18:01:38.249607392 +0200
+@@ -1508,7 +1508,7 @@ int sh_redirect(Shell_t *shp,struct iono
+ fn = fd;
+ if(fd<10)
+ {
+- if((fn=fcntl(fd,F_DUPFD,10)) < 0)
++ if((fn=sh_fcntl(fd,F_DUPFD,10)) < 0)
+ goto fail;
+ if(fn>=shp->gd->lim.open_max && !sh_iovalidfd(shp,fn))
+ goto fail;
+diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.fdstatus ksh-20120801/src/cmd/ksh93/sh/subshell.c
+--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.fdstatus 2012-07-17 23:54:21.000000000 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2013-07-04 17:56:20.342000310 +0200
+@@ -122,7 +122,7 @@ void sh_subtmpfile(Shell_t *shp)
+ register struct checkpt *pp = (struct checkpt*)shp->jmplist;
+ register struct subshell *sp = subshell_data->pipe;
+ /* save file descriptor 1 if open */
+- if((sp->tmpfd = fd = fcntl(1,F_DUPFD,10)) >= 0)
++ if((sp->tmpfd = fd = sh_fcntl(1,F_DUPFD,10)) >= 0)
+ {
+ fcntl(fd,F_SETFD,FD_CLOEXEC);
+ shp->fdstatus[fd] = shp->fdstatus[1]|IOCLEX;
+@@ -554,7 +554,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
+ sp->pwdfd = n;
+ if(n<10)
+ {
+- sp->pwdfd = fcntl(n,F_DUPFD,10);
++ sp->pwdfd = sh_fcntl(n,F_DUPFD,10);
+ close(n);
+ }
+ if(sp->pwdfd>0)
+diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.fdstatus ksh-20120801/src/cmd/ksh93/sh/xec.c
+--- ksh-20120801/src/cmd/ksh93/sh/xec.c.fdstatus 2012-07-23 16:49:32.000000000 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2013-07-04 17:57:47.153712116 +0200
+@@ -116,7 +116,7 @@ static int iousepipe(Shell_t *shp)
+ return(0);
+ usepipe++;
+ fcntl(subpipe[0],F_SETFD,FD_CLOEXEC);
+- subpipe[2] = fcntl(1,F_DUPFD,10);
++ subpipe[2] = sh_fcntl(1,F_DUPFD,10);
+ fcntl(subpipe[2],F_SETFD,FD_CLOEXEC);
+ shp->fdstatus[subpipe[2]] = shp->fdstatus[1];
+ close(1);
+@@ -3622,7 +3622,7 @@ static void coproc_init(Shell_t *shp, in
+ sh_pipe(shp->cpipe);
+ if((outfd=shp->cpipe[1]) < 10)
+ {
+- int fd=fcntl(shp->cpipe[1],F_DUPFD,10);
++ int fd=sh_fcntl(shp->cpipe[1],F_DUPFD,10);
+ if(fd>=10)
+ {
+ shp->fdstatus[fd] = (shp->fdstatus[outfd]&~IOCLEX);
diff --git a/source/ap/ksh93/patches/ksh-20100621-manfix3.patch b/source/ap/ksh93/patches/ksh-20100621-manfix3.patch
new file mode 100644
index 000000000..bced57514
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20100621-manfix3.patch
@@ -0,0 +1,12 @@
+diff -up ksh-20100621/src/cmd/ksh93/sh.1.manfix3 ksh-20100621/src/cmd/ksh93/sh.1
+--- ksh-20100621/src/cmd/ksh93/sh.1.manfix3 2013-05-02 13:07:51.180529762 +0200
++++ ksh-20100621/src/cmd/ksh93/sh.1 2013-05-02 13:11:30.469327199 +0200
+@@ -7585,7 +7585,7 @@ file descriptor 2.
+ If the
+ .B \-i
+ option is present or
+-if the shell input and output are attached to a terminal (as told by
++if the shell input and error output are attached to a terminal (as told by
+ .IR tcgetattr (2)),
+ then this shell is
+ .IR interactive .
diff --git a/source/ap/ksh93/patches/ksh-20120801-alarmifs.patch b/source/ap/ksh93/patches/ksh-20120801-alarmifs.patch
new file mode 100644
index 000000000..88b0ba9e5
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-alarmifs.patch
@@ -0,0 +1,33 @@
+--- ksh-20120801/src/cmd/ksh93/sh/init.c 2014-12-10 20:11:17.693446084 -0200
++++ ksh-20120801/src/cmd/ksh93/sh/init.c 2014-12-10 20:11:24.753442619 -0200
+@@ -576,6 +576,7 @@ static char* get_ifs(register Namval_t*
+ shp->ifstable[' '] = shp->ifstable['\t'] = S_SPACE;
+ shp->ifstable['\n'] = S_NL;
+ }
++ shp->ifstable[0] = S_EOF;
+ }
+ return(value);
+ }
+--- ksh-20120801/src/cmd/ksh93/bltins/alarm.c 2014-12-18 12:03:39.198461933 -0200
++++ ksh-20120801/src/cmd/ksh93/bltins/alarm.c 2014-12-18 12:04:32.464421268 -0200
+@@ -130,6 +130,7 @@ void sh_timetraps(Shell_t *shp)
+ {
+ register struct tevent *tp, *tpnext;
+ register struct tevent *tptop;
++ char ifstable[256];
+ while(1)
+ {
+ shp->sigflag[SIGALRM] &= ~SH_SIGALRM;
+@@ -141,7 +142,11 @@ void sh_timetraps(Shell_t *shp)
+ {
+ tp->flags &= ~L_FLAG;
+ if(tp->action)
++ {
++ memcpy(ifstable,shp->ifstable,sizeof(ifstable));
+ sh_fun(tp->action,tp->node,(char**)0);
++ memcpy(shp->ifstable,ifstable,sizeof(ifstable));
++ }
+ tp->flags &= ~L_FLAG;
+ if(!tp->flags)
+ {
+
diff --git a/source/ap/ksh93/patches/ksh-20120801-argvfix.patch b/source/ap/ksh93/patches/ksh-20120801-argvfix.patch
new file mode 100644
index 000000000..b0e1a7823
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-argvfix.patch
@@ -0,0 +1,13 @@
+diff -up ksh-20120801/src/cmd/ksh93/sh/main.c.fixargs ksh-20120801/src/cmd/ksh93/sh/main.c
+--- ksh-20120801/src/cmd/ksh93/sh/main.c.fixargs 2013-12-31 11:32:14.917874134 +0100
++++ ksh-20120801/src/cmd/ksh93/sh/main.c 2013-12-31 11:32:58.028847126 +0100
+@@ -757,7 +757,7 @@ static void fixargs(char **argv, int mod
+ offset += size;
+ buff[offset++] = ' ';
+ }
+- buff[offset-1] = 0;
++ memset(&buff[offset - 1], 0, command_len - offset + 1);
+ # ifdef PSTAT
+ un.pst_command = stakptr(0);
+ pstat(PSTAT_SETCMD,un,0,0,0);
+
diff --git a/source/ap/ksh93/patches/ksh-20120801-assoc-unset-leak.patch b/source/ap/ksh93/patches/ksh-20120801-assoc-unset-leak.patch
new file mode 100644
index 000000000..1af7d1664
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-assoc-unset-leak.patch
@@ -0,0 +1,20 @@
+diff -up ksh-20120801/src/cmd/ksh93/sh/name.c.orig ksh-20120801/src/cmd/ksh93/sh/name.c
+--- ksh-20120801/src/cmd/ksh93/sh/name.c.orig 2015-02-10 17:15:37.180783550 -0200
++++ ksh-20120801/src/cmd/ksh93/sh/name.c 2015-02-10 18:25:51.726228437 -0200
+@@ -1298,7 +1298,16 @@ void nv_delete(Namval_t* np, Dt_t *root,
+ if(dtdelete(root,np))
+ {
+ if(!(flags&NV_NOFREE) && ((flags&NV_FUNCTION) || !nv_subsaved(np,flags&NV_TABLE)))
++ {
++ Namarr_t *ap;
++ if(nv_isarray(np) && np->nvfun && (ap=nv_arrayptr(np)) && array_assoc(ap)) {
++ while(nv_associative(np,0,NV_ANEXT))
++ nv_associative(np, 0, NV_ADELETE);
++ nv_associative(np, 0, NV_AFREE);
++ free((void*)np->nvfun);
++ }
+ free((void*)np);
++ }
+ }
+ #if 0
+ else
diff --git a/source/ap/ksh93/patches/ksh-20120801-cdfix3.patch b/source/ap/ksh93/patches/ksh-20120801-cdfix3.patch
new file mode 100644
index 000000000..7e47f711e
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-cdfix3.patch
@@ -0,0 +1,12 @@
+diff -up ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.cdfix3 ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c
+--- ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.cdfix3 2014-06-20 12:39:02.757407689 +0200
++++ ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c 2014-06-20 12:40:19.530998070 +0200
+@@ -290,7 +290,7 @@ int b_cd(int argc, char *argv[],Shbltin_
+ if(newdirfd >=0)
+ {
+ /* chdir for directories on HSM/tapeworms may take minutes */
+- if(fchdir(newdirfd) >= 0)
++ if((rval=fchdir(newdirfd)) >= 0)
+ {
+ if(shp->pwdfd >= 0)
+ sh_close(shp->pwdfd);
diff --git a/source/ap/ksh93/patches/ksh-20120801-cdfork.patch b/source/ap/ksh93/patches/ksh-20120801-cdfork.patch
new file mode 100644
index 000000000..c82cb4c00
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-cdfork.patch
@@ -0,0 +1,40 @@
+--- ksh-20120801/src/cmd/ksh93/sh/path.c 2014-09-01 15:08:06.738969962 -0300
++++ ksh-20120801/src/cmd/ksh93/sh/path.c 2014-09-01 15:13:51.321459978 -0300
+@@ -229,13 +229,12 @@ static pid_t path_xargs(Shell_t *shp,con
+ /*
+ * make sure PWD is set up correctly
+ * Return the present working directory
+- * Invokes getcwd() if flag==0 and if necessary
++ * Invokes getcwd() if necessary
+ * Sets the PWD variable to this value
+ */
+ char *path_pwd(Shell_t *shp,int flag)
+ {
+ register char *cp;
+- register char *dfault = (char*)e_dot;
+ register int count = 0;
+ if(shp->pwd)
+ return((char*)shp->pwd);
+@@ -254,11 +253,6 @@ char *path_pwd(Shell_t *shp,int flag)
+ cp = "/";
+ break;
+ case 3:
+- cp = (char*)e_crondir;
+- if(flag) /* skip next case when non-zero flag */
+- ++count;
+- break;
+- case 4:
+ {
+ if(cp=getcwd(NIL(char*),0))
+ {
+@@ -269,8 +263,8 @@ char *path_pwd(Shell_t *shp,int flag)
+ }
+ break;
+ }
+- case 5:
++ case 4:
+- return(dfault);
++ return((char*)e_dot);
+ }
+ if(cp && *cp=='/' && test_inode(cp,e_dot))
+ break;
diff --git a/source/ap/ksh93/patches/ksh-20120801-covsfix.patch b/source/ap/ksh93/patches/ksh-20120801-covsfix.patch
new file mode 100644
index 000000000..c64e2a79e
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-covsfix.patch
@@ -0,0 +1,58 @@
+diff -up ksh-20120801/src/cmd/ksh93/sh/init.c.covsfix ksh-20120801/src/cmd/ksh93/sh/init.c
+--- ksh-20120801/src/cmd/ksh93/sh/init.c.covsfix 2013-07-22 17:41:34.674054068 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/init.c 2013-07-22 17:42:50.761361921 +0200
+@@ -1237,9 +1237,11 @@ static void put_mode(Namval_t* np, const
+ mode = *(double*)val;
+ }
+ else
++ {
+ mode = strperm(val, &last,0);
+- if(*last)
+- errormsg(SH_DICT,ERROR_exit(1),"%s: invalid mode string",val);
++ if(*last)
++ errormsg(SH_DICT,ERROR_exit(1),"%s: invalid mode string",val);
++ }
+ nv_putv(np,(char*)&mode,NV_INTEGER,nfp);
+ }
+ else
+diff -up ksh-20120801/src/cmd/ksh93/sh/io.c.covsfix ksh-20120801/src/cmd/ksh93/sh/io.c
+--- ksh-20120801/src/cmd/ksh93/sh/io.c.covsfix 2013-07-22 17:06:30.282927080 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/io.c 2013-07-22 17:08:49.645721280 +0200
+@@ -954,6 +954,7 @@ int sh_pipe(register int pv[])
+ socklen_t slen;
+ if ((pv[out] = socket (AF_INET, SOCK_STREAM, 0)) < 0)
+ errormsg(SH_DICT,ERROR_system(1),e_pipe);
++ memset(&sin.sin_zero, 0, sizeof(sin.sin_zero));
+ do
+ {
+ sin.sin_family = AF_INET;
+diff -up ksh-20120801/src/cmd/ksh93/sh/name.c.covsfix ksh-20120801/src/cmd/ksh93/sh/name.c
+--- ksh-20120801/src/cmd/ksh93/sh/name.c.covsfix 2013-07-22 17:40:31.644635604 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/name.c 2013-07-22 17:41:15.828227073 +0200
+@@ -3094,6 +3094,7 @@ void nv_newattr (register Namval_t *np,
+ if(!mp)
+ nv_putval (np, cp, NV_RDONLY);
+ free(cp);
++ cp = NULL;
+ }
+ }
+ while(ap && nv_nextsub(np));
+diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.covsfix ksh-20120801/src/cmd/ksh93/sh/subshell.c
+--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.covsfix 2013-07-22 17:46:15.607533423 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2013-07-22 17:48:36.739290968 +0200
+@@ -205,7 +205,14 @@ void sh_subfork(void)
+ shp->comsub = 0;
+ SH_SUBSHELLNOD->nvalue.s = 0;
+ sp->subpid=0;
+- shp->st.trapcom[0] = (comsub==2?NULL:trap);
++ if (comsub==2)
++ {
++ shp->st.trapcom[0] = NULL;
++ if(trap)
++ free((void*)trap);
++ }
++ else
++ shp->st.trapcom[0] = (comsub==2?NULL:trap);
+ shp->savesig = 0;
+ }
+ }
diff --git a/source/ap/ksh93/patches/ksh-20120801-crash.patch b/source/ap/ksh93/patches/ksh-20120801-crash.patch
new file mode 100644
index 000000000..63eda7229
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-crash.patch
@@ -0,0 +1,64 @@
+diff -up ksh-20120801/src/cmd/ksh93/include/jobs.h.crash ksh-20120801/src/cmd/ksh93/include/jobs.h
+--- ksh-20120801/src/cmd/ksh93/include/jobs.h.crash 2014-07-16 17:32:03.570057304 +0200
++++ ksh-20120801/src/cmd/ksh93/include/jobs.h 2014-07-16 17:32:03.600057172 +0200
+@@ -118,6 +118,7 @@ struct jobs
+ char jobcontrol; /* turned on for real job control */
+ char waitsafe; /* wait will not block */
+ char waitall; /* wait for all jobs in pipe */
++ char hack1_waitall;
+ char toclear; /* job table needs clearing */
+ unsigned char *freejobs; /* free jobs numbers */
+ #if SHOPT_COSHELL
+diff -up ksh-20120801/src/cmd/ksh93/sh/jobs.c.crash ksh-20120801/src/cmd/ksh93/sh/jobs.c
+--- ksh-20120801/src/cmd/ksh93/sh/jobs.c.crash 2014-07-16 17:32:03.554057375 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/jobs.c 2014-07-16 17:32:03.600057172 +0200
+@@ -1957,6 +1957,7 @@ again:
+ {
+ count = bp->count;
+ jp = bp->list;
++ jpold = 0;
+ goto again;
+ }
+ if(jp)
+diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.crash ksh-20120801/src/cmd/ksh93/sh/subshell.c
+--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.crash 2014-07-16 17:32:03.593057203 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2014-07-16 17:32:03.600057172 +0200
+@@ -492,6 +492,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
+ struct sh_scoped savst;
+ struct dolnod *argsav=0;
+ int argcnt;
++ int pipefail = 0;
+ memset((char*)sp, 0, sizeof(*sp));
+ sfsync(shp->outpool);
+ sh_sigcheck(shp);
+@@ -541,7 +542,10 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
+ sp->comsub = shp->comsub;
+ shp->subshare = comsub==2 || (comsub==1 && sh_isoption(SH_SUBSHARE));
+ if(comsub)
++ {
+ shp->comsub = comsub;
++ job.hack1_waitall=(comsub==1);
++ }
+ sp->shpwdfd=-1;
+ if(!comsub || !shp->subshare)
+ {
+@@ -648,6 +652,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
+ }
+ else
+ {
++ job.hack1_waitall=0;
+ /* move tmp file to iop and restore sfstdout */
+ iop = sfswap(sfstdout,NIL(Sfio_t*));
+ if(!iop)
+diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.crash ksh-20120801/src/cmd/ksh93/sh/xec.c
+--- ksh-20120801/src/cmd/ksh93/sh/xec.c.crash 2014-07-16 17:32:03.587057230 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2014-07-16 17:32:03.601057168 +0200
+@@ -2125,7 +2125,7 @@ int sh_exec(register const Shnode_t *t,
+ memset(exitval,0,job.waitall*sizeof(int));
+ }
+ else
+- job.waitall |= !pipejob && sh_isstate(SH_MONITOR);
++ job.waitall |= job.hack1_waitall || !pipejob && sh_isstate(SH_MONITOR);
+ job_lock();
+ nlock++;
+ do
diff --git a/source/ap/ksh93/patches/ksh-20120801-diskfull.patch b/source/ap/ksh93/patches/ksh-20120801-diskfull.patch
new file mode 100644
index 000000000..9d68d9350
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-diskfull.patch
@@ -0,0 +1,20 @@
+--- ksh-20120801/src/cmd/ksh93/sh/main.c 2015-04-17 16:55:57.802048900 -0300
++++ ksh-20120801/src/cmd/ksh93/sh/main.c 2015-04-17 17:10:45.276129709 -0300
+@@ -423,7 +423,7 @@ static void exfile(register Shell_t *shp
+ sfsync(shp->outpool);
+ shp->st.execbrk = shp->st.breakcnt = 0;
+ /* check for return from profile or env file */
+- if(sh_isstate(SH_PROFILE) && (jmpval==SH_JMPFUN || jmpval==SH_JMPEXIT))
++ if(sh_isstate(SH_PROFILE) && (jmpval==SH_JMPFUN || jmpval==SH_JMPEXIT || jmpval==SH_JMPERREXIT))
+ {
+ sh_setstate(states);
+ goto done;
+@@ -600,6 +600,8 @@ done:
+ siglongjmp(*shp->jmplist,jmpval);
+ else if(jmpval == SH_JMPEXIT)
+ sh_done(shp,0);
++ else if(jmpval == SH_JMPERREXIT)
++ sh_done(shp,-1);
+ if(fno>0)
+ sh_close(fno);
+ if(shp->st.filename)
diff --git a/source/ap/ksh93/patches/ksh-20120801-emptyarrayinit.patch b/source/ap/ksh93/patches/ksh-20120801-emptyarrayinit.patch
new file mode 100644
index 000000000..c888b319d
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-emptyarrayinit.patch
@@ -0,0 +1,11 @@
+--- ksh-20120801/src/cmd/ksh93/sh/array.c 2014-12-11 16:39:34.253860675 -0200
++++ ksh-20120801/src/cmd/ksh93/sh/array.c 2014-12-11 16:39:40.794857083 -0200
+@@ -1003,7 +1003,7 @@ Namarr_t *nv_setarray(Namval_t *np, void
+ ap->nelem = nelem;
+ ap->fun = fun;
+ nv_onattr(np,NV_ARRAY);
+- if(fp || value)
++ if(fp || (value && value != Empty))
+ {
+ nv_putsub(np, "0", ARRAY_ADD);
+ if(value)
diff --git a/source/ap/ksh93/patches/ksh-20120801-fd2lost.patch b/source/ap/ksh93/patches/ksh-20120801-fd2lost.patch
new file mode 100644
index 000000000..fbb76070e
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-fd2lost.patch
@@ -0,0 +1,64 @@
+diff -up ksh-20120801/src/cmd/ksh93/sh/macro.c.orig ksh-20120801/src/cmd/ksh93/sh/macro.c
+--- ksh-20120801/src/cmd/ksh93/sh/macro.c.orig 2013-12-09 13:13:22.153525239 +0100
++++ ksh-20120801/src/cmd/ksh93/sh/macro.c 2013-12-09 13:20:58.144635385 +0100
+@@ -391,7 +391,7 @@ void sh_machere(Shell_t *shp,Sfio_t *inf
+ break;
+ }
+ case S_PAR:
+- comsubst(mp,(Shnode_t*)0,1);
++ comsubst(mp,(Shnode_t*)0,3);
+ break;
+ case S_EOF:
+ if((c=fcfill()) > 0)
+@@ -1165,7 +1165,7 @@ retry1:
+ case S_PAR:
+ if(type)
+ goto nosub;
+- comsubst(mp,(Shnode_t*)0,1);
++ comsubst(mp,(Shnode_t*)0,3);
+ return(1);
+ case S_DIG:
+ var = 0;
+@@ -2152,10 +2152,12 @@ static void comsubst(Mac_t *mp,register
+ mp->ifsp = nv_getval(np);
+ stkset(stkp,savptr,savtop);
+ newlines = 0;
+- if(type/*==3 - don't break `` vs $() */ && mp->shp->spid)
++ if(type==3 && mp->shp->spid)
+ {
+ job_wait(mp->shp->spid);
+- mp->shp->spid = 0;
++ if(mp->shp->pipepid==mp->shp->spid)
++ mp->shp->spid = 0;
++ mp->shp->pipepid = 0;
+ }
+ sfsetbuf(sp,(void*)sp,0);
+ bufsize = sfvalue(sp);
+diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.anotherfix ksh-20120801/src/cmd/ksh93/sh/subshell.c
+--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.anotherfix 2014-01-20 14:43:46.410416327 +0100
++++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2014-01-20 14:43:46.444416042 +0100
+@@ -122,7 +122,8 @@ void sh_subtmpfile(Shell_t *shp)
+ else if(errno!=EBADF)
+ errormsg(SH_DICT,ERROR_system(1),e_toomany);
+ /* popping a discipline forces a /tmp file create */
+- sfdisc(sfstdout,SF_POPDISC);
++ if(shp->comsub != 1)
++ sfdisc(sfstdout,SF_POPDISC);
+ if((fd=sffileno(sfstdout))<0)
+ {
+ /* unable to create the /tmp file so use a pipe */
+diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.anotherfix ksh-20120801/src/cmd/ksh93/sh/xec.c
+--- ksh-20120801/src/cmd/ksh93/sh/xec.c.anotherfix 2014-01-20 14:47:30.527524008 +0100
++++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2014-01-20 14:47:30.563523703 +0100
+@@ -1773,7 +1773,11 @@ int sh_exec(register const Shnode_t *t,
+ if(shp->pipepid)
+ shp->pipepid = parent;
+ else
++ {
+ job_wait(parent);
++ if(parent==shp->spid)
++ shp->spid = 0;
++ }
+ if(shp->topfd > topfd)
+ sh_iorestore(shp,topfd,0);
+ if(usepipe && tsetio && subdup && unpipe)
diff --git a/source/ap/ksh93/patches/ksh-20120801-filecomsubst.patch b/source/ap/ksh93/patches/ksh-20120801-filecomsubst.patch
new file mode 100644
index 000000000..6aa1fea91
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-filecomsubst.patch
@@ -0,0 +1,11 @@
+diff -up ksh-20120801/src/cmd/ksh93/sh/io.c.filecombsubst ksh-20120801/src/cmd/ksh93/sh/io.c
+--- ksh-20120801/src/cmd/ksh93/sh/io.c.filecombsubst 2014-02-26 16:15:52.355391420 +0100
++++ ksh-20120801/src/cmd/ksh93/sh/io.c 2014-02-26 16:23:55.588148801 +0100
+@@ -1326,6 +1326,7 @@ int sh_redirect(Shell_t *shp,struct iono
+ if(flag==SH_SHOWME)
+ goto traceit;
+ fd=sh_chkopen(fname);
++ fd=sh_iomovefd(fd);
+ }
+ else if(sh_isoption(SH_RESTRICTED))
+ errormsg(SH_DICT,ERROR_exit(1),e_restricted,fname);
diff --git a/source/ap/ksh93/patches/ksh-20120801-forkbomb.patch b/source/ap/ksh93/patches/ksh-20120801-forkbomb.patch
new file mode 100644
index 000000000..7a1a5c169
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-forkbomb.patch
@@ -0,0 +1,12 @@
+diff -up ksh-20120801/src/cmd/ksh93/sh/fault.c.forkbomb ksh-20120801/src/cmd/ksh93/sh/fault.c
+--- ksh-20120801/src/cmd/ksh93/sh/fault.c.forkbomb 2013-04-30 16:20:40.237490109 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/fault.c 2013-04-30 16:21:49.961068778 +0200
+@@ -519,7 +519,7 @@ void sh_exit(register int xno)
+ if(pp && pp->mode>1)
+ cursig = -1;
+ #ifdef SIGTSTP
+- if(shp->trapnote&SH_SIGTSTP)
++ if((shp->trapnote&SH_SIGTSTP) && job.jobcontrol)
+ {
+ /* ^Z detected by the shell */
+ shp->trapnote = 0;
diff --git a/source/ap/ksh93/patches/ksh-20120801-fununset.patch b/source/ap/ksh93/patches/ksh-20120801-fununset.patch
new file mode 100644
index 000000000..1f5cb17c1
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-fununset.patch
@@ -0,0 +1,12 @@
+diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.fununset ksh-20120801/src/cmd/ksh93/sh/xec.c
+--- ksh-20120801/src/cmd/ksh93/sh/xec.c.fununset 2014-06-16 14:21:09.293513844 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2014-06-16 14:21:09.309513760 +0200
+@@ -3570,7 +3570,7 @@ static void sh_funct(Shell_t *shp,Namval
+ #endif
+ nv_putval(SH_PATHNAMENOD,shp->st.filename,NV_NOFREE);
+ shp->pipepid = pipepid;
+- np->nvalue.rp->running -= 2;
++ if (np->nvalue.rp) np->nvalue.rp->running -= 2;
+ }
+
+ /*
diff --git a/source/ap/ksh93/patches/ksh-20120801-heresub.patch b/source/ap/ksh93/patches/ksh-20120801-heresub.patch
new file mode 100644
index 000000000..880071cd6
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-heresub.patch
@@ -0,0 +1,32 @@
+diff -up ksh-20120801/src/cmd/ksh93/sh/lex.c.heresub ksh-20120801/src/cmd/ksh93/sh/lex.c
+--- ksh-20120801/src/cmd/ksh93/sh/lex.c.heresub 2014-05-21 16:48:42.635700984 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/lex.c 2014-05-21 16:48:42.678700772 +0200
+@@ -1557,6 +1557,7 @@ static int comsub(register Lex_t *lp, in
+ {
+ register int n,c,count=1;
+ register int line=lp->sh->inlineno;
++ struct ionod *inheredoc = lp->heredoc;
+ char *first,*cp=fcseek(0),word[5];
+ int off, messages=0, assignok=lp->assignok, csub;
+ struct lexstate save;
+@@ -1683,7 +1684,7 @@ done:
+ lp->lexd.dolparen--;
+ lp->lex = save;
+ lp->assignok = (endchar(lp)==RBRACT?assignok:0);
+- if(lp->heredoc)
++ if(lp->heredoc && !inheredoc)
+ errormsg(SH_DICT,ERROR_exit(SYNBAD),e_lexsyntax5,lp->sh->inlineno,lp->heredoc->ioname);
+ return(messages);
+ }
+diff -up ksh-20120801/src/cmd/ksh93/sh/macro.c.heresub ksh-20120801/src/cmd/ksh93/sh/macro.c
+--- ksh-20120801/src/cmd/ksh93/sh/macro.c.heresub 2014-05-21 16:48:42.650700910 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/macro.c 2014-05-21 16:48:42.678700772 +0200
+@@ -2085,7 +2085,7 @@ static void comsubst(Mac_t *mp,register
+ }
+ sfputc(stkp,c);
+ }
+- sfputc(stkp,' ');
++ sfputc(stkp,'\n');
+ c = stktell(stkp);
+ str=stkfreeze(stkp,1);
+ /* disable verbose and don't save in history file */
diff --git a/source/ap/ksh93/patches/ksh-20120801-kshmfix.patch b/source/ap/ksh93/patches/ksh-20120801-kshmfix.patch
new file mode 100644
index 000000000..cc6840666
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-kshmfix.patch
@@ -0,0 +1,66 @@
+diff -up ksh-20120801/src/cmd/ksh93/sh/main.c.monintoron ksh-20120801/src/cmd/ksh93/sh/main.c
+--- ksh-20120801/src/cmd/ksh93/sh/main.c.monintoron 2013-05-31 10:15:02.738828102 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/main.c 2013-05-31 10:15:36.057095262 +0200
+@@ -406,10 +406,10 @@ static void exfile(register Shell_t *shp
+ {
+ buff.mode = SH_JMPEXIT;
+ sh_onoption(SH_TRACKALL);
+- sh_offoption(SH_MONITOR);
+ }
+ sh_offstate(SH_INTERACTIVE);
+- sh_offstate(SH_MONITOR);
++ if(sh_isoption(SH_MONITOR))
++ sh_onstate(SH_MONITOR);
+ sh_offstate(SH_HISTORY);
+ sh_offoption(SH_HISTORY);
+ }
+diff -up ksh-20120801/src/cmd/ksh93/sh/jobs.c.orig ksh-20120801/src/cmd/ksh93/sh/jobs.c
+--- ksh-20120801/src/cmd/ksh93/sh/jobs.c.orig 2013-05-31 10:12:28.358590452 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/jobs.c 2013-05-31 10:16:51.203697890 +0200
+@@ -548,7 +548,7 @@ int job_reap(register int sig)
+ {
+ px = job_byjid((int)pw->p_job);
+ for(; px && (px->p_flag&P_DONE); px=px->p_nxtproc);
+- if(!px)
++ if(!px && sh_isoption(SH_INTERACTIVE))
+ tcsetpgrp(JOBTTY,job.mypid);
+ }
+ #ifndef SHOPT_BGX
+@@ -842,10 +842,11 @@ static void job_set(register struct proc
+
+ static void job_reset(register struct process *pw)
+ {
++ Shell_t *shp = pw->p_shp;
+ /* save the terminal state for current job */
+ #ifdef SIGTSTP
+ job_fgrp(pw,tcgetpgrp(job.fd));
+- if(tcsetpgrp(job.fd,job.mypid) !=0)
++ if(sh_isoption(SH_INTERACTIVE) && tcsetpgrp(job.fd,job.mypid) !=0)
+ return;
+ #endif /* SIGTSTP */
+ /* force the following tty_get() to do a tcgetattr() unless fg */
+diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.orig ksh-20120801/src/cmd/ksh93/sh/xec.c
+--- ksh-20120801/src/cmd/ksh93/sh/xec.c.orig 2013-05-31 10:12:27.000000000 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2013-05-31 10:18:14.650367185 +0200
+@@ -2201,7 +2201,7 @@ int sh_exec(register const Shnode_t *t,
+ }
+ shp->exitval = n;
+ #ifdef SIGTSTP
+- if(!pipejob && sh_isstate(SH_MONITOR))
++ if(!pipejob && sh_isstate(SH_MONITOR) && sh_isoption(SH_INTERACTIVE))
+ tcsetpgrp(JOBTTY,shp->gd->pid);
+ #endif /*SIGTSTP */
+ job.curpgid = savepgid;
+diff -up ksh-20120801/src/cmd/ksh93/edit/edit.c.kshmfix ksh-20120801/src/cmd/ksh93/edit/edit.c
+--- ksh-20120801/src/cmd/ksh93/edit/edit.c.kshmfix 2013-09-23 10:46:57.007256192 +0200
++++ ksh-20120801/src/cmd/ksh93/edit/edit.c 2013-09-23 10:47:43.988937610 +0200
+@@ -1050,7 +1050,7 @@ int ed_getchar(register Edit_t *ep,int m
+ {
+ if(mode<=0 && -c == ep->e_intr)
+ {
+- sh_fault(SIGINT);
++ killpg(getpgrp(),SIGINT);
+ siglongjmp(ep->e_env, UINTR);
+ }
+ if(mode<=0 && ep->sh->st.trap[SH_KEYTRAP])
+
diff --git a/source/ap/ksh93/patches/ksh-20120801-lexfix.patch b/source/ap/ksh93/patches/ksh-20120801-lexfix.patch
new file mode 100644
index 000000000..9150da80d
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-lexfix.patch
@@ -0,0 +1,56 @@
+diff -up ksh-20120801/src/cmd/ksh93/edit/edit.c.trajfiks ksh-20120801/src/cmd/ksh93/edit/edit.c
+--- ksh-20120801/src/cmd/ksh93/edit/edit.c.trajfiks 2012-08-02 00:18:19.000000000 +0200
++++ ksh-20120801/src/cmd/ksh93/edit/edit.c 2014-02-06 12:12:11.570942651 +0100
+@@ -53,6 +53,7 @@
+
+ static char CURSOR_UP[20] = { ESC, '[', 'A', 0 };
+ static char KILL_LINE[20] = { ESC, '[', 'J', 0 };
++static char *savelex;
+
+
+
+@@ -232,6 +233,8 @@ int tty_set(int fd, int action, struct t
+ void tty_cooked(register int fd)
+ {
+ register Edit_t *ep = (Edit_t*)(shgd->ed_context);
++ if(ep->sh->st.trap[SH_KEYTRAP] && savelex)
++ memcpy(ep->sh->lex_context,savelex,ep->sh->lexsize);
+ ep->e_keytrap = 0;
+ if(ep->e_raw==0)
+ return;
+@@ -783,6 +786,13 @@ void ed_setup(register Edit_t *ep, int f
+ ep->e_lbuf[n] = *pp++;
+ ep->e_default = 0;
+ }
++ if(ep->sh->st.trap[SH_KEYTRAP])
++ {
++ if(!savelex)
++ savelex = (char*)malloc(shp->lexsize);
++ if(savelex)
++ memcpy(savelex, ep->sh->lex_context, ep->sh->lexsize);
++ }
+ }
+
+ static void ed_putstring(register Edit_t *ep, const char *str)
+diff -up ksh-20120801/src/cmd/ksh93/include/defs.h.trajfiks ksh-20120801/src/cmd/ksh93/include/defs.h
+--- ksh-20120801/src/cmd/ksh93/include/defs.h.trajfiks 2014-02-06 12:18:13.149091836 +0100
++++ ksh-20120801/src/cmd/ksh93/include/defs.h 2014-02-06 12:18:13.175091784 +0100
+@@ -224,6 +224,7 @@ struct shared
+ int xargexit; \
+ int nenv; \
+ mode_t mask; \
++ int lexsize; \
+ Env_t *env; \
+ void *init_context; \
+ void *mac_context; \
+diff -up ksh-20120801/src/cmd/ksh93/sh/lex.c.trajfiks ksh-20120801/src/cmd/ksh93/sh/lex.c
+--- ksh-20120801/src/cmd/ksh93/sh/lex.c.trajfiks 2014-02-06 12:19:13.587950320 +0100
++++ ksh-20120801/src/cmd/ksh93/sh/lex.c 2014-02-06 12:19:13.623950219 +0100
+@@ -268,6 +268,7 @@ Lex_t *sh_lexopen(Lex_t *lp, Shell_t *sp
+ {
+ lp = (Lex_t*)newof(0,Lex_t,1,0);
+ lp->sh = sp;
++ sp->lexsize = sizeof(Lex_t);
+ }
+ fcnotify(lex_advance,lp);
+ lp->lex.intest = lp->lex.incase = lp->lex.skipword = lp->lexd.warn = 0;
diff --git a/source/ap/ksh93/patches/ksh-20120801-locking.patch b/source/ap/ksh93/patches/ksh-20120801-locking.patch
new file mode 100644
index 000000000..189d254d5
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-locking.patch
@@ -0,0 +1,26 @@
+diff -up ksh-20120801/src/cmd/ksh93/include/jobs.h.locking ksh-20120801/src/cmd/ksh93/include/jobs.h
+--- ksh-20120801/src/cmd/ksh93/include/jobs.h.locking 2014-06-27 15:51:07.144923719 +0200
++++ ksh-20120801/src/cmd/ksh93/include/jobs.h 2014-06-27 15:52:56.463272276 +0200
+@@ -149,15 +149,18 @@ extern struct jobs job;
+ #define vmbusy() 0
+ #endif
+
+-#define job_lock() (job.in_critical++)
++#define asoincint(p) __sync_fetch_and_add(p,1)
++#define asodecint(p) __sync_fetch_and_sub(p,1)
++
++#define job_lock() asoincint(&job.in_critical)
+ #define job_unlock() \
+ do { \
+ int sig; \
+- if (!--job.in_critical && (sig = job.savesig)) \
++ if (asodecint(&job.in_critical)==1 && (sig = job.savesig)) \
+ { \
+- if (!job.in_critical++ && !vmbusy()) \
++ if (!asoincint(&job.in_critical) && !vmbusy()) \
+ job_reap(sig); \
+- job.in_critical--; \
++ asodecint(&job.in_critical); \
+ } \
+ } while(0)
+
diff --git a/source/ap/ksh93/patches/ksh-20120801-macro.patch b/source/ap/ksh93/patches/ksh-20120801-macro.patch
new file mode 100644
index 000000000..ca8024ef7
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-macro.patch
@@ -0,0 +1,205 @@
+diff -up ksh-20120801/src/cmd/ksh93/include/io.h.macro ksh-20120801/src/cmd/ksh93/include/io.h
+--- ksh-20120801/src/cmd/ksh93/include/io.h.macro 2012-07-18 16:12:38.000000000 +0200
++++ ksh-20120801/src/cmd/ksh93/include/io.h 2013-07-04 16:14:05.809595966 +0200
+@@ -81,6 +81,7 @@ extern void sh_iosave(Shell_t *, int,in
+ extern int sh_iovalidfd(Shell_t*, int);
+ extern int sh_inuse(Shell_t*, int);
+ extern void sh_iounsave(Shell_t*);
++extern void iounpipe(Shell_t*);
+ extern int sh_chkopen(const char*);
+ extern int sh_ioaccess(int,int);
+ extern int sh_devtofd(const char*);
+diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.macro ksh-20120801/src/cmd/ksh93/sh/subshell.c
+--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.macro 2013-07-04 16:14:05.783595751 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2013-07-04 16:15:46.673432991 +0200
+@@ -171,7 +171,7 @@ void sh_subfork(void)
+ {
+ register struct subshell *sp = subshell_data;
+ Shell_t *shp = sp->shp;
+- int curenv = shp->curenv;
++ int curenv = shp->curenv, comsub=shp->comsub;
+ pid_t pid;
+ char *trap = shp->st.trapcom[0];
+ if(trap)
+@@ -204,7 +204,7 @@ void sh_subfork(void)
+ shp->comsub = 0;
+ SH_SUBSHELLNOD->nvalue.s = 0;
+ sp->subpid=0;
+- shp->st.trapcom[0] = trap;
++ shp->st.trapcom[0] = (comsub==2?NULL:trap);
+ shp->savesig = 0;
+ }
+ }
+@@ -743,7 +743,6 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
+ fchdir(shp->pwdfd);
+ }
+ shp->subshare = sp->subshare;
+- shp->comsub = sp->comsub;
+ shp->subdup = sp->subdup;
+ #if SHOPT_COSHELL
+ shp->coshell = sp->coshell;
+@@ -773,7 +772,12 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
+ if(nsig>0)
+ kill(getpid(),nsig);
+ if(sp->subpid)
++ {
+ job_wait(sp->subpid);
++ if(comsub>1)
++ iounpipe(shp);
++ }
++ shp->comsub = sp->comsub;
+ if(comsub && iop && sp->pipefd<0)
+ sfseek(iop,(off_t)0,SEEK_SET);
+ if(shp->trapnote)
+diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.macro ksh-20120801/src/cmd/ksh93/sh/xec.c
+--- ksh-20120801/src/cmd/ksh93/sh/xec.c.macro 2013-07-04 16:14:05.800595891 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2013-07-04 16:14:05.810595975 +0200
+@@ -102,11 +102,11 @@ struct funenv
+ * temp file.
+ */
+ static int subpipe[3],subdup,tsetio,usepipe;
+-static void iounpipe(Shell_t*);
++void iounpipe(Shell_t*);
+
+-static int iousepipe(Shell_t *shp)
++int iousepipe(Shell_t *shp)
+ {
+- int i;
++ int fd=sffileno(sfstdout),i,err=errno;
+ if(usepipe)
+ {
+ usepipe++;
+@@ -115,13 +115,18 @@ static int iousepipe(Shell_t *shp)
+ if(sh_rpipe(subpipe) < 0)
+ return(0);
+ usepipe++;
+- fcntl(subpipe[0],F_SETFD,FD_CLOEXEC);
+- subpipe[2] = sh_fcntl(1,F_DUPFD,10);
+- fcntl(subpipe[2],F_SETFD,FD_CLOEXEC);
++ if(shp->comsub!=1)
++ {
++ subpipe[2] = sh_fcntl(subpipe[1],F_DUPFD,10);
++ sh_close(subpipe[1]);
++ return(1);
++ }
++ subpipe[2] = sh_fcntl(fd,F_dupfd_cloexec,10);
+ shp->fdstatus[subpipe[2]] = shp->fdstatus[1];
+- close(1);
+- fcntl(subpipe[1],F_DUPFD,1);
+- shp->fdstatus[1] = shp->fdstatus[subpipe[1]];
++ while(close(fd)<0 && errno==EINTR)
++ errno = err;
++ fcntl(subpipe[1],F_DUPFD,fd);
++ shp->fdstatus[1] = shp->fdstatus[subpipe[1]]&~IOCLEX;
+ sh_close(subpipe[1]);
+ if(subdup=shp->subdup) for(i=0; i < 10; i++)
+ {
+@@ -135,14 +140,23 @@ static int iousepipe(Shell_t *shp)
+ return(1);
+ }
+
+-static void iounpipe(Shell_t *shp)
++void iounpipe(Shell_t *shp)
+ {
+- int n;
++ int fd=sffileno(sfstdout),n,err=errno;
+ char buff[SF_BUFSIZE];
+- close(1);
+- fcntl(subpipe[2], F_DUPFD, 1);
+- shp->fdstatus[1] = shp->fdstatus[subpipe[2]];
++ if(!usepipe)
++ return;
+ --usepipe;
++ if(shp->comsub>1)
++ {
++ sh_close(subpipe[2]);
++ while(read(subpipe[0],buff,sizeof(buff))>0);
++ goto done;
++ }
++ while(close(fd)<0 && errno==EINTR)
++ errno = err;
++ fcntl(subpipe[2], F_DUPFD, fd);
++ shp->fdstatus[1] = shp->fdstatus[subpipe[2]];
+ if(subdup) for(n=0; n < 10; n++)
+ {
+ if(subdup&(1<<n))
+@@ -174,6 +188,7 @@ static void iounpipe(Shell_t *shp)
+ else if(errno!=EINTR)
+ break;
+ }
++done:
+ sh_close(subpipe[0]);
+ subpipe[0] = -1;
+ tsetio = 0;
+@@ -725,7 +740,7 @@ static void unset_instance(Namval_t *nq,
+ }
+
+ #if SHOPT_COSHELL
+-uintmax_t coused;
++static uintmax_t coused;
+ /*
+ * print out function definition
+ */
+@@ -1619,10 +1634,14 @@ int sh_exec(register const Shnode_t *t,
+ if(shp->subshell)
+ {
+ sh_subtmpfile(shp);
+- if(shp->comsub==1 && !(shp->fdstatus[1]&IONOSEEK))
+- unpipe=iousepipe(shp);
+ if((type&(FAMP|TFORK))==(FAMP|TFORK))
+- sh_subfork();
++ {
++ if(shp->comsub && !(shp->fdstatus[1]&IONOSEEK))
++ {
++ unpipe = iousepipe(shp);
++ sh_subfork();
++ }
++ }
+ }
+ no_fork = !ntflag && !(type&(FAMP|FPOU)) && !shp->subshell &&
+ !(shp->st.trapcom[SIGINT] && *shp->st.trapcom[SIGINT]) &&
+@@ -3495,8 +3514,7 @@ static void sh_funct(Shell_t *shp,Namval
+ struct funenv fun;
+ char *fname = nv_getval(SH_FUNNAMENOD);
+ struct Level *lp =(struct Level*)(SH_LEVELNOD->nvfun);
+- int level, pipepid=shp->pipepid, comsub=shp->comsub;
+- shp->comsub = 0;
++ int level, pipepid=shp->pipepid;
+ shp->pipepid = 0;
+ sh_stats(STAT_FUNCT);
+ if(!lp->hdr.disc)
+@@ -3539,7 +3557,6 @@ static void sh_funct(Shell_t *shp,Namval
+ lp->maxlevel = level;
+ SH_LEVELNOD->nvalue.s = lp->maxlevel;
+ shp->last_root = nv_dict(DOTSHNOD);
+- shp->comsub = comsub;
+ #if 0
+ nv_putval(SH_FUNNAMENOD,shp->st.funname,NV_NOFREE);
+ #else
+diff -up ksh-20120801/src/cmd/ksh93/sh/macro.c.orig ksh-20120801/src/cmd/ksh93/sh/macro.c
+--- ksh-20120801/src/cmd/ksh93/sh/macro.c.orig 2012-06-29 20:05:47.000000000 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/macro.c 2013-08-12 18:06:17.291843164 +0200
+@@ -2152,6 +2152,11 @@ static void comsubst(Mac_t *mp,register
+ mp->ifsp = nv_getval(np);
+ stkset(stkp,savptr,savtop);
+ newlines = 0;
++ if(type/*==3 - don't break `` vs $() */ && mp->shp->spid)
++ {
++ job_wait(mp->shp->spid);
++ mp->shp->spid = 0;
++ }
+ sfsetbuf(sp,(void*)sp,0);
+ bufsize = sfvalue(sp);
+ /* read command substitution output and put on stack or here-doc */
+diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.orig ksh-20120801/src/cmd/ksh93/sh/xec.c
+--- ksh-20120801/src/cmd/ksh93/sh/xec.c.orig 2013-08-12 18:06:57.567497226 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2013-08-12 18:20:36.443454280 +0200
+@@ -1734,6 +1734,8 @@ int sh_exec(register const Shnode_t *t,
+ nlock--;
+ job_unlock();
+ }
++ if(shp->subshell)
++ shp->spid = parent;
+ if(type&FPCL)
+ sh_close(shp->inpipe[0]);
+ if(type&(FCOOP|FAMP))
diff --git a/source/ap/ksh93/patches/ksh-20120801-manfix4.patch b/source/ap/ksh93/patches/ksh-20120801-manfix4.patch
new file mode 100644
index 000000000..635544518
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-manfix4.patch
@@ -0,0 +1,12 @@
+diff -up ksh-20120801/src/cmd/ksh93/sh.1.manfix4 ksh-20120801/src/cmd/ksh93/sh.1
+--- ksh-20120801/src/cmd/ksh93/sh.1.manfix4 2014-05-22 12:04:51.593750721 +0200
++++ ksh-20120801/src/cmd/ksh93/sh.1 2014-05-22 12:05:32.561556452 +0200
+@@ -4147,7 +4147,7 @@ command are ignored if the command is fo
+ .B &
+ and the
+ .B monitor
+-option is not active.
++option is active.
+ Otherwise, signals have the values
+ inherited by the shell from its parent
+ (but see also
diff --git a/source/ap/ksh93/patches/ksh-20120801-memlik.patch b/source/ap/ksh93/patches/ksh-20120801-memlik.patch
new file mode 100644
index 000000000..31f1eb998
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-memlik.patch
@@ -0,0 +1,37 @@
+diff -up ksh-20120801/src/cmd/ksh93/sh/array.c.memlik ksh-20120801/src/cmd/ksh93/sh/array.c
+--- ksh-20120801/src/cmd/ksh93/sh/array.c.memlik 2012-06-07 00:00:42.000000000 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/array.c 2013-06-11 16:52:47.557123973 +0200
+@@ -1701,7 +1701,11 @@ void *nv_associative(register Namval_t *
+ ap->header.scope = 0;
+ }
+ else
+- dtclose(ap->header.table);
++ {
++ if((ap->header.nelem&ARRAY_MASK)==0 && (ap->cur=nv_search("0",ap->header.table,0)))
++ nv_associative(np,(char*)0,NV_ADELETE);
++ dtclose(ap->header.table);
++ }
+ return((void*)ap);
+ case NV_ANEXT:
+ if(!ap->pos)
+diff -up ksh-20120801/src/cmd/ksh93/sh/name.c.memlik ksh-20120801/src/cmd/ksh93/sh/name.c
+--- ksh-20120801/src/cmd/ksh93/sh/name.c.memlik 2012-07-23 18:21:57.000000000 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/name.c 2013-06-11 16:19:41.036648218 +0200
+@@ -2465,6 +2465,8 @@ static void table_unset(Shell_t *shp, re
+ }
+ }
+ npnext = (Namval_t*)dtnext(root,np);
++ if(nv_arrayptr(np))
++ nv_putsub(np,NIL(char*),ARRAY_SCAN);
+ _nv_unset(np,flags);
+ nv_delete(np,root,0);
+ }
+@@ -3326,7 +3328,7 @@ int nv_rename(register Namval_t *np, int
+ shp->last_root = last_root;
+ if(flags&NV_MOVE)
+ {
+- if(arraynp && !nv_isattr(np,NV_MINIMAL) && (mp=(Namval_t*)np->nvenv) && (ap=nv_arrayptr(mp)))
++ if(arraynp && !nv_isattr(np,NV_MINIMAL) && (mp=(Namval_t*)np->nvenv) && (ap=nv_arrayptr(mp)) && !ap->fun)
+ ap->nelem++;
+ }
+ if((nv_arrayptr(nr) && !arraynr) || nv_isvtree(nr))
diff --git a/source/ap/ksh93/patches/ksh-20120801-memlik3.patch b/source/ap/ksh93/patches/ksh-20120801-memlik3.patch
new file mode 100644
index 000000000..9df57d2ec
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-memlik3.patch
@@ -0,0 +1,76 @@
+diff -up ksh-20120801/src/cmd/ksh93/include/name.h.memlik3 ksh-20120801/src/cmd/ksh93/include/name.h
+--- ksh-20120801/src/cmd/ksh93/include/name.h.memlik3 2012-05-10 18:33:41.000000000 +0200
++++ ksh-20120801/src/cmd/ksh93/include/name.h 2014-01-22 14:14:32.774483776 +0100
+@@ -215,7 +215,7 @@ extern Namval_t *nv_mount(Namval_t*, co
+ extern Namval_t *nv_arraychild(Namval_t*, Namval_t*, int);
+ extern int nv_compare(Dt_t*, Void_t*, Void_t*, Dtdisc_t*);
+ extern void nv_outnode(Namval_t*,Sfio_t*, int, int);
+-extern int nv_subsaved(Namval_t*);
++extern int nv_subsaved(Namval_t*,int);
+ extern void nv_typename(Namval_t*, Sfio_t*);
+ extern void nv_newtype(Namval_t*);
+ extern int nv_istable(Namval_t*);
+diff -up ksh-20120801/src/cmd/ksh93/sh/name.c.memlik3 ksh-20120801/src/cmd/ksh93/sh/name.c
+--- ksh-20120801/src/cmd/ksh93/sh/name.c.memlik3 2014-01-22 14:14:32.751483987 +0100
++++ ksh-20120801/src/cmd/ksh93/sh/name.c 2014-01-22 14:14:32.775483767 +0100
+@@ -1297,7 +1297,7 @@ void nv_delete(Namval_t* np, Dt_t *root,
+ {
+ if(dtdelete(root,np))
+ {
+- if(!(flags&NV_NOFREE) && ((flags&NV_FUNCTION) || !nv_subsaved(np)))
++ if(!(flags&NV_NOFREE) && ((flags&NV_FUNCTION) || !nv_subsaved(np,flags&NV_TABLE)))
+ free((void*)np);
+ }
+ #if 0
+@@ -2461,14 +2461,14 @@ static void table_unset(Shell_t *shp, re
+ {
+ _nv_unset(nq,flags);
+ npnext = (Namval_t*)dtnext(root,nq);
+- nv_delete(nq,root,0);
++ nv_delete(nq,root,NV_TABLE);
+ }
+ }
+ npnext = (Namval_t*)dtnext(root,np);
+ if(nv_arrayptr(np))
+ nv_putsub(np,NIL(char*),ARRAY_SCAN);
+ _nv_unset(np,flags);
+- nv_delete(np,root,0);
++ nv_delete(np,root,NV_TABLE);
+ }
+ }
+
+diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.memlik3 ksh-20120801/src/cmd/ksh93/sh/subshell.c
+--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.memlik3 2014-01-22 14:14:32.768483831 +0100
++++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2014-01-22 14:20:50.810236676 +0100
+@@ -218,16 +218,28 @@ void sh_subfork(void)
+ }
+ }
+
+-int nv_subsaved(register Namval_t *np)
++int nv_subsaved(register Namval_t *np,int table)
+ {
+ register struct subshell *sp;
+- register struct Link *lp;
++ register struct Link *lp, *lpprev;
+ for(sp = (struct subshell*)subshell_data; sp; sp=sp->prev)
+ {
+- for(lp=sp->svar; lp; lp = lp->next)
++ lpprev = 0;
++ for(lp=sp->svar; lp; lpprev=lp, lp=lp->next)
+ {
+ if(lp->node==np)
++ {
++ if(table&NV_TABLE)
++ {
++ if(lpprev)
++ lpprev->next = lp->next;
++ else
++ sp->svar = lp->next;
++ free((void*)np);
++ free((void*)lp);
++ }
+ return(1);
++ }
+ }
+ }
+ return(0);
diff --git a/source/ap/ksh93/patches/ksh-20120801-mlikfiks.patch b/source/ap/ksh93/patches/ksh-20120801-mlikfiks.patch
new file mode 100644
index 000000000..fbf016ae1
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-mlikfiks.patch
@@ -0,0 +1,34 @@
+diff -up ksh-20120801/src/cmd/ksh93/sh/lex.c.mlikfiks ksh-20120801/src/cmd/ksh93/sh/lex.c
+--- ksh-20120801/src/cmd/ksh93/sh/lex.c.mlikfiks 2013-07-22 12:45:30.923170264 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/lex.c 2013-07-22 12:46:25.235556905 +0200
+@@ -2465,7 +2465,7 @@ static int alias_exceptf(Sfio_t *iop,int
+ if(dp!=handle)
+ sfdisc(iop,dp);
+ }
+- else if(type==SF_FINAL)
++ else if(type==SF_DPOP || type==SF_FINAL)
+ free((void*)ap);
+ goto done;
+ }
+diff -up ksh-20120801/src/cmd/ksh93/sh/path.c.mlikfiks ksh-20120801/src/cmd/ksh93/sh/path.c
+--- ksh-20120801/src/cmd/ksh93/sh/path.c.mlikfiks 2013-07-22 12:47:23.149990016 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/path.c 2013-07-22 12:48:33.363283877 +0200
+@@ -613,6 +613,7 @@ static void funload(Shell_t *shp,int fno
+ }
+ while((rp=dtnext(shp->fpathdict,rp)) && strcmp(pname,rp->fname)==0);
+ sh_close(fno);
++ free((void*)pname);
+ return;
+ }
+ sh_onstate(SH_NOLOG);
+diff -up ksh-20120801/src/cmd/ksh93/sh/macro.c.aliasfix ksh-20120801/src/cmd/ksh93/sh/macro.c
+--- ksh-20120801/src/cmd/ksh93/sh/macro.c.aliasfix 2013-07-29 15:03:45.841680475 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/macro.c 2013-07-29 15:04:23.871336821 +0200
+@@ -2085,6 +2085,7 @@ static void comsubst(Mac_t *mp,register
+ }
+ sfputc(stkp,c);
+ }
++ sfputc(stkp,' ');
+ c = stktell(stkp);
+ str=stkfreeze(stkp,1);
+ /* disable verbose and don't save in history file */
diff --git a/source/ap/ksh93/patches/ksh-20120801-mtty.patch b/source/ap/ksh93/patches/ksh-20120801-mtty.patch
new file mode 100644
index 000000000..d992a8804
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-mtty.patch
@@ -0,0 +1,12 @@
+diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.mtty ksh-20120801/src/cmd/ksh93/sh/xec.c
+--- ksh-20120801/src/cmd/ksh93/sh/xec.c.mtty 2014-01-22 16:52:06.441608750 +0100
++++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2014-01-22 16:52:06.485608361 +0100
+@@ -3163,7 +3169,7 @@ pid_t _sh_fork(Shell_t *shp,register pid
+ * completed. Make parent the job group id.
+ */
+ if(postid==0)
+- job.curpgid = parent;
++ job.curpgid = job.jobcontrol?parent:getpid();
+ if(job.jobcontrol || (flags&FAMP))
+ {
+ if(setpgid(parent,job.curpgid)<0 && errno==EPERM)
diff --git a/source/ap/ksh93/patches/ksh-20120801-noexeccdfix.patch b/source/ap/ksh93/patches/ksh-20120801-noexeccdfix.patch
new file mode 100644
index 000000000..47128e09b
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-noexeccdfix.patch
@@ -0,0 +1,40 @@
+From b8260293a8ed7849a358291faae7b58f4a05dcc9 Mon Sep 17 00:00:00 2001
+From: Kamil Dudka <kdudka@redhat.com>
+Date: Mon, 10 Nov 2014 18:23:34 +0100
+Subject: [PATCH] Resolves: #1160923 - handle failure of fchdir()
+
+... and chdir()
+---
+ src/cmd/ksh93/bltins/cd_pwd.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/src/cmd/ksh93/bltins/cd_pwd.c b/src/cmd/ksh93/bltins/cd_pwd.c
+index a972da6..c20959c 100644
+--- a/src/cmd/ksh93/bltins/cd_pwd.c
++++ b/src/cmd/ksh93/bltins/cd_pwd.c
+@@ -329,18 +329,20 @@ int b_cd(int argc, char *argv[],Shbltin_t *context)
+ if(newdirfd >=0)
+ {
+ /* chdir for directories on HSM/tapeworms may take minutes */
+- if(fchdir(newdirfd) >= 0)
++ if((rval=fchdir(newdirfd)) >= 0)
+ {
+ if(shp->pwdfd >= 0)
+ sh_close(shp->pwdfd);
+ shp->pwdfd=newdirfd;
+ goto success;
+ }
++ else
++ sh_close(newdirfd);
+ }
+ #ifndef O_SEARCH
+ else
+ {
+- if(chdir(dir) >=0)
++ if((rval=chdir(dir)) >=0)
+ {
+ if(shp->pwdfd >= 0)
+ {
+--
+2.1.0
+
diff --git a/source/ap/ksh93/patches/ksh-20120801-nohupfork.patch b/source/ap/ksh93/patches/ksh-20120801-nohupfork.patch
new file mode 100644
index 000000000..20cdeb905
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-nohupfork.patch
@@ -0,0 +1,11 @@
+diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.nohupfork ksh-20120801/src/cmd/ksh93/sh/xec.c
+--- ksh-20120801/src/cmd/ksh93/sh/xec.c.nohupfork 2015-08-27 14:25:38.925378019 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2015-08-27 14:30:42.267058087 +0200
+@@ -2067,6 +2067,7 @@ int sh_exec(register const Shnode_t *t,
+ {
+ sh_exec(t->par.partre,flags);
+ shp->st.trapcom[0]=0;
++ sh_offoption(SH_INTERACTIVE);
+ sh_done(shp,0);
+ }
+ }
diff --git a/source/ap/ksh93/patches/ksh-20120801-nomulti.patch b/source/ap/ksh93/patches/ksh-20120801-nomulti.patch
new file mode 100644
index 000000000..5d7e7a4e2
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-nomulti.patch
@@ -0,0 +1,11 @@
+diff -up ksh-20120801/src/cmd/ksh93/sh/init.c.nomulti ksh-20120801/src/cmd/ksh93/sh/init.c
+--- ksh-20120801/src/cmd/ksh93/sh/init.c.nomulti 2013-10-08 20:46:46.202471042 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/init.c 2013-10-08 20:46:57.912331483 +0200
+@@ -1446,7 +1446,6 @@ Shell_t *sh_init(register int argc,regis
+ #endif /* SHOPT_TIMEOUT */
+ /* initialize jobs table */
+ job_clear();
+- sh_onoption(SH_MULTILINE);
+ if(argc>0)
+ {
+ /* check for restricted shell */
diff --git a/source/ap/ksh93/patches/ksh-20120801-oldenvinit.patch b/source/ap/ksh93/patches/ksh-20120801-oldenvinit.patch
new file mode 100644
index 000000000..8ee086314
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-oldenvinit.patch
@@ -0,0 +1,95 @@
+diff -up ksh-20120801/src/cmd/ksh93/sh/init.c.fixset ksh-20120801/src/cmd/ksh93/sh/init.c
+--- ksh-20120801/src/cmd/ksh93/sh/init.c.fixset 2014-11-03 15:45:36.510997271 +0100
++++ ksh-20120801/src/cmd/ksh93/sh/init.c 2014-11-03 16:20:44.398917280 +0100
+@@ -2003,8 +2003,91 @@ static Dt_t *inittree(Shell_t *shp,const
+ * skip over items that are not name-value pairs
+ */
+
++
+ static void env_init(Shell_t *shp)
+ {
++ register char *cp;
++ register Namval_t *np;
++ register char **ep=environ;
++ register char *next=0;
++#ifdef _ENV_H
++ shp->env = env_open(environ,3);
++ env_delete(shp->env,"_");
++#endif
++ if(ep)
++ {
++ while(cp= *ep++)
++ {
++ if(*cp=='A' && cp[1]=='_' && cp[2]=='_' && cp[3]=='z' && cp[4]=='=')
++ next = cp+4;
++ else if(np=nv_open(cp,shp->var_tree,(NV_EXPORT|NV_IDENT|NV_ASSIGN|NV_NOFAIL)))
++ {
++ nv_onattr(np,NV_IMPORT);
++ np->nvenv = cp;
++ nv_close(np);
++ }
++ else /* swap with front */
++ {
++ ep[-1] = environ[shp->nenv];
++ environ[shp->nenv++] = cp;
++ }
++ }
++ while(cp=next)
++ {
++ if(next = strchr(++cp,'='))
++ *next = 0;
++ np = nv_search(cp+2,shp->var_tree,NV_ADD);
++ if(np!=SHLVL && nv_isattr(np,NV_IMPORT|NV_EXPORT))
++ {
++ int flag = *(unsigned char*)cp-' ';
++ int size = *(unsigned char*)(cp+1)-' ';
++ if((flag&NV_INTEGER) && size==0)
++ {
++ /* check for floating*/
++ char *ep,*val = nv_getval(np);
++ strtol(val,&ep,10);
++ if(*ep=='.' || *ep=='e' || *ep=='E')
++ {
++ char *lp;
++ flag |= NV_DOUBLE;
++ if(*ep=='.')
++ {
++ strtol(ep+1,&lp,10);
++ if(*lp)
++ ep = lp;
++ }
++ if(*ep && *ep!='.')
++ {
++ flag |= NV_EXPNOTE;
++ size = ep-val;
++ }
++ else
++ size = strlen(ep);
++ size--;
++ }
++ }
++ nv_newattr(np,flag|NV_IMPORT|NV_EXPORT,size);
++ }
++ else
++ cp += 2;
++ }
++ }
++#ifdef _ENV_H
++ env_delete(shp->env,e_envmarker);
++#endif
++ if(nv_isnull(PWDNOD) || nv_isattr(PWDNOD,NV_TAGGED))
++ {
++ nv_offattr(PWDNOD,NV_TAGGED);
++ path_pwd(shp,0);
++ }
++ if((cp = nv_getval(SHELLNOD)) && (sh_type(cp)&SH_TYPE_RESTRICTED))
++ sh_onoption(SH_RESTRICTED); /* restricted shell */
++ return;
++}
++
++
++static void env_init_backup(Shell_t *shp)
++{
+ register char *cp;
+ register Namval_t *np,*mp;
+ register char **ep=environ;
diff --git a/source/ap/ksh93/patches/ksh-20120801-retfix.patch b/source/ap/ksh93/patches/ksh-20120801-retfix.patch
new file mode 100644
index 000000000..bcb5b3326
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-retfix.patch
@@ -0,0 +1,20 @@
+diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.retfix ksh-20120801/src/cmd/ksh93/sh/subshell.c
+--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.retfix 2014-09-01 13:50:02.956085721 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2014-09-01 13:54:01.104818416 +0200
+@@ -652,6 +652,16 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
+ }
+ else
+ {
++ if(comsub!=1 && shp->spid)
++ {
++ int c = shp->exitval;
++ job_wait(shp->spid);
++ shp->exitval = c;
++ exitset();
++ if(shp->pipepid==shp->spid)
++ shp->spid = 0;
++ shp->pipepid = 0;
++ }
+ job.hack1_waitall=0;
+ /* move tmp file to iop and restore sfstdout */
+ iop = sfswap(sfstdout,NIL(Sfio_t*));
diff --git a/source/ap/ksh93/patches/rmdirfix.patch b/source/ap/ksh93/patches/ksh-20120801-rmdirfix.patch
index 132de7dba..ae9dfd72d 100644
--- a/source/ap/ksh93/patches/rmdirfix.patch
+++ b/source/ap/ksh93/patches/ksh-20120801-rmdirfix.patch
@@ -69,7 +69,7 @@ diff -up ksh20120801/src/cmd/ksh93/sh/subshell.c.orig ksh20120801/src/cmd/ksh93/
- sp->pwdfd = n;
- if(n<10)
- {
-- sp->pwdfd = fcntl(n,F_DUPFD,10);
+- sp->pwdfd = sh_fcntl(n,F_DUPFD,10);
- close(n);
- }
- if(sp->pwdfd>0)
diff --git a/source/ap/ksh93/patches/ksh-20120801-roundit.patch b/source/ap/ksh93/patches/ksh-20120801-roundit.patch
new file mode 100644
index 000000000..015bc85cd
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-roundit.patch
@@ -0,0 +1,12 @@
+diff -up ksh-20120801/src/lib/libast/sfio/sfcvt.c.rounditgood ksh-20120801/src/lib/libast/sfio/sfcvt.c
+--- ksh-20120801/src/lib/libast/sfio/sfcvt.c.rounditgood 2014-02-27 16:45:54.630161032 +0100
++++ ksh-20120801/src/lib/libast/sfio/sfcvt.c 2014-02-27 16:45:54.658161205 +0100
+@@ -491,7 +491,7 @@ int format; /* conversion format */
+ *decpt += 1;
+ if(!(format&SFFMT_EFORMAT))
+ { /* add one more 0 for %f precision */
+- ep[-1] = '0';
++ if(ep-sp>1) ep[-1] = '0';
+ ep += 1;
+ }
+ }
diff --git a/source/ap/ksh93/patches/ksh-20120801-sufix.patch b/source/ap/ksh93/patches/ksh-20120801-sufix.patch
new file mode 100644
index 000000000..b820e1cfc
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-sufix.patch
@@ -0,0 +1,11 @@
+diff -up ksh-20120801/src/cmd/ksh93/sh/io.c.sufix ksh-20120801/src/cmd/ksh93/sh/io.c
+--- ksh-20120801/src/cmd/ksh93/sh/io.c.sufix 2014-04-08 14:30:14.412343555 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/io.c 2014-04-08 14:31:18.403876587 +0200
+@@ -2144,6 +2144,7 @@ static int io_prompt(Shell_t *shp,Sfio_t
+ }
+ #endif /* TIOCLBIC */
+ cp = sh_mactry(shp,nv_getval(sh_scoped(shp,PS1NOD)));
++ shp->exitval = 0;
+ for(;c= *cp;cp++)
+ {
+ if(c==HIST_CHAR)
diff --git a/source/ap/ksh93/patches/ksh-20120801-tpstl.patch b/source/ap/ksh93/patches/ksh-20120801-tpstl.patch
new file mode 100644
index 000000000..41e17c87d
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-tpstl.patch
@@ -0,0 +1,12 @@
+diff -up ksh-20120801/src/cmd/ksh93/sh/init.c.tpstl ksh-20120801/src/cmd/ksh93/sh/init.c
+--- ksh-20120801/src/cmd/ksh93/sh/init.c.tpstl 2014-04-03 11:21:25.395547276 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/init.c 2014-04-03 11:26:03.908867208 +0200
+@@ -332,7 +332,7 @@ static Namfun_t *clone_optindex(Namval_t
+ /* Trap for restricted variables FPATH, PATH, SHELL, ENV */
+ static void put_restricted(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
+ {
+- Shell_t *shp = nv_shell(np);
++ Shell_t *shp = sh_getinterp();
+ int path_scoped = 0, fpath_scoped=0;
+ Pathcomp_t *pp;
+ char *name = nv_name(np);
diff --git a/source/ap/ksh93/patches/ksh-20120801-trapcom.patch b/source/ap/ksh93/patches/ksh-20120801-trapcom.patch
new file mode 100644
index 000000000..a900b5437
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-trapcom.patch
@@ -0,0 +1,47 @@
+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;
diff --git a/source/ap/ksh93/patches/ksh-20120801-xufix.patch b/source/ap/ksh93/patches/ksh-20120801-xufix.patch
new file mode 100644
index 000000000..496e0bf77
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20120801-xufix.patch
@@ -0,0 +1,29 @@
+diff -up ksh-20120801/src/cmd/ksh93/bltins/typeset.c.xufix ksh-20120801/src/cmd/ksh93/bltins/typeset.c
+--- ksh-20120801/src/cmd/ksh93/bltins/typeset.c.xufix 2015-02-03 14:47:23.266022137 +0100
++++ ksh-20120801/src/cmd/ksh93/bltins/typeset.c 2015-02-03 14:47:23.308022046 +0100
+@@ -93,6 +93,8 @@ int b_readonly(int argc,char *argv[],
+ memset((void*)&tdata,0,sizeof(tdata));
+ tdata.sh = context->shp;
+ tdata.aflag = '-';
++ /* do not change size */
++ tdata.argnum = -1;
+ while((flag = optget(argv,*command=='e'?sh_optexport:sh_optreadonly))) switch(flag)
+ {
+ case 'p':
+diff -up ksh-20120801/src/cmd/ksh93/sh/name.c.xufix ksh-20120801/src/cmd/ksh93/sh/name.c
+--- ksh-20120801/src/cmd/ksh93/sh/name.c.xufix 2015-02-03 14:47:23.281022105 +0100
++++ ksh-20120801/src/cmd/ksh93/sh/name.c 2015-02-03 14:52:08.768404194 +0100
+@@ -3019,10 +3019,12 @@ void nv_newattr (register Namval_t *np,
+ nv_onattr(np,NV_EXPORT);
+ sh_envput(shp->env,np);
+ }
+- if((n^newatts)==NV_EXPORT)
++ if((n^newatts)==NV_EXPORT && size==-1)
+ return;
+ }
+ oldsize = nv_size(np);
++ if (size == -1)
++ size = oldsize;
+ if((size==oldsize|| (n&NV_INTEGER)) && !trans && ((n^newatts)&~NV_NOCHANGE)==0)
+ {
+ if(size)
diff --git a/source/ap/ksh93/patches/ksh-20130613-cdfix4.patch b/source/ap/ksh93/patches/ksh-20130613-cdfix4.patch
new file mode 100644
index 000000000..5b2901750
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20130613-cdfix4.patch
@@ -0,0 +1,15 @@
+diff -up ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.cdfix4 ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c
+--- ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.cdfix4 2014-08-26 15:24:57.276953822 +0200
++++ ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c 2014-08-26 15:25:34.738770361 +0200
+@@ -143,9 +143,9 @@ int sh_diropenat(Shell_t *shp, int dir,
+ }
+
+ /* Move fd to a number > 10 and *register* the fd number with the shell */
+- shfd = sh_fcntl(fd, F_dupfd_cloexec, 10);
++ shfd = fcntl(fd, F_dupfd_cloexec, 10);
+ savederrno=errno;
+- sh_close(fd);
++ close(fd);
+ errno=savederrno;
+ return(shfd);
+ }
diff --git a/source/ap/ksh93/patches/ksh-20130628-longer.patch b/source/ap/ksh93/patches/ksh-20130628-longer.patch
new file mode 100644
index 000000000..4761a3476
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20130628-longer.patch
@@ -0,0 +1,58 @@
+diff -up ksh-20120801/src/cmd/ksh93/include/defs.h.longer ksh-20120801/src/cmd/ksh93/include/defs.h
+--- ksh-20120801/src/cmd/ksh93/include/defs.h.longer 2012-06-25 20:47:47.000000000 +0200
++++ ksh-20120801/src/cmd/ksh93/include/defs.h 2013-07-08 17:33:42.238534376 +0200
+@@ -162,8 +162,8 @@ struct shared
+ Namval_t *prev_table; /* previous table used in nv_open */ \
+ Sfio_t *outpool; /* ouput stream pool */ \
+ long timeout; /* read timeout */ \
+- short curenv; /* current subshell number */ \
+- short jobenv; /* subshell number for jobs */ \
++ long curenv; /* current subshell number */ \
++ long jobenv; /* subshell number for jobs */ \
+ int infd; /* input file descriptor */ \
+ short nextprompt; /* next prompt is PS<nextprompt> */ \
+ short poolfiles; \
+diff -up ksh-20120801/src/cmd/ksh93/include/jobs.h.longer ksh-20120801/src/cmd/ksh93/include/jobs.h
+--- ksh-20120801/src/cmd/ksh93/include/jobs.h.longer 2011-12-19 13:36:37.000000000 +0100
++++ ksh-20120801/src/cmd/ksh93/include/jobs.h 2013-07-08 17:32:52.881124147 +0200
+@@ -87,7 +87,7 @@ struct process
+ unsigned short p_exit; /* exit value or signal number */
+ unsigned short p_exitmin; /* minimum exit value for xargs */
+ unsigned short p_flag; /* flags - see below */
+- int p_env; /* subshell environment number */
++ long p_env; /* subshell environment number */
+ #ifdef JOBS
+ off_t p_name; /* history file offset for command */
+ struct termios p_stty; /* terminal state for job */
+diff -up ksh-20120801/src/cmd/ksh93/sh/jobs.c.longer ksh-20120801/src/cmd/ksh93/sh/jobs.c
+diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.longer ksh-20120801/src/cmd/ksh93/sh/subshell.c
+--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.longer 2013-07-08 17:32:52.874124090 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2013-07-08 17:32:52.882124156 +0200
+@@ -98,7 +98,7 @@ static struct subshell
+ #endif /* SHOPT_COSHELL */
+ } *subshell_data;
+
+-static int subenv;
++static long subenv;
+
+
+ /*
+@@ -171,7 +171,8 @@ void sh_subfork(void)
+ {
+ register struct subshell *sp = subshell_data;
+ Shell_t *shp = sp->shp;
+- int curenv = shp->curenv, comsub=shp->comsub;
++ long curenv = shp->curenv;
++ int comsub=shp->comsub;
+ pid_t pid;
+ char *trap = shp->st.trapcom[0];
+ if(trap)
+@@ -461,7 +462,7 @@ 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 savecurenv = shp->curenv;
++ long savecurenv = shp->curenv;
+ int savejobpgid = job.curpgid;
+ int *saveexitval = job.exitval;
+ int16_t subshell;
diff --git a/source/ap/ksh93/patches/ksh-20140301-fikspand.patch b/source/ap/ksh93/patches/ksh-20140301-fikspand.patch
new file mode 100644
index 000000000..9899392f4
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20140301-fikspand.patch
@@ -0,0 +1,12 @@
+diff -up ksh-20120801/src/cmd/ksh93/sh/expand.c.fikspand ksh-20120801/src/cmd/ksh93/sh/expand.c
+--- ksh-20120801/src/cmd/ksh93/sh/expand.c.fikspand 2010-11-24 05:46:30.000000000 +0100
++++ ksh-20120801/src/cmd/ksh93/sh/expand.c 2014-05-22 12:55:46.252717371 +0200
+@@ -278,6 +278,8 @@ int path_generate(Shell_t *shp,struct ar
+ char comma, range=0;
+ int first, last, incr, count = 0;
+ char tmp[32], end[1];
++ if(!sh_isoption(SH_BRACEEXPAND))
++ return path_expand(shp,todo->argval,arghead);
+ todo->argchn.ap = 0;
+ again:
+ apin = ap = todo;
diff --git a/source/ap/ksh93/patches/ksh-20140415-hokaido.patch b/source/ap/ksh93/patches/ksh-20140415-hokaido.patch
new file mode 100644
index 000000000..5ff69279f
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20140415-hokaido.patch
@@ -0,0 +1,37 @@
+diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.hokaido ksh-20120801/src/cmd/ksh93/sh/xec.c
+--- ksh-20120801/src/cmd/ksh93/sh/xec.c.hokaido 2014-09-18 14:41:57.696756230 +0200
++++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2014-09-18 14:43:55.439205247 +0200
+@@ -1633,12 +1633,20 @@ int sh_exec(register const Shnode_t *t,
+ #endif /* SHOPT_COSHELL */
+ if(shp->subshell)
+ {
++ int comsubsave = shp->comsub;
++ if(comsubsave==1)
++ shp->comsub = 2;
+ sh_subtmpfile(shp);
++ shp->comsub = comsubsave;
++ if(shp->comsub==1 && (!(shp->fdstatus[1]&IONOSEEK)))
++ unpipe = iousepipe(shp);
++
+ if((type&(FAMP|TFORK))==(FAMP|TFORK))
+ {
+ if(shp->comsub && !(shp->fdstatus[1]&IONOSEEK))
+ {
+- unpipe = iousepipe(shp);
++ if (!unpipe)
++ unpipe = iousepipe(shp);
+ sh_subfork();
+ }
+ }
+@@ -2107,7 +2115,11 @@ int sh_exec(register const Shnode_t *t,
+ job.curjobid = 0;
+ if(shp->subshell)
+ {
++ int comsubsave = shp->comsub;
++ if(comsubsave==1)
++ shp->comsub = 2;
+ sh_subtmpfile(shp);
++ shp->comsub = comsubsave;
+ if(shp->comsub==1 && !(shp->fdstatus[1]&IONOSEEK))
+ iousepipe(shp);
+ }
diff --git a/source/ap/ksh93/patches/ksh-20140801-arraylen.patch b/source/ap/ksh93/patches/ksh-20140801-arraylen.patch
new file mode 100644
index 000000000..34c9b6bd9
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20140801-arraylen.patch
@@ -0,0 +1,11 @@
+--- ksh-20120801/src/cmd/ksh93/sh/xec.c 2015-04-02 10:55:26.228017873 -0400
++++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2015-04-02 10:56:04.099017700 -0400
+@@ -1234,7 +1234,7 @@ int sh_exec(register const Shnode_t *t,
+ if((io||argn))
+ {
+ Shbltin_t *bp=0;
+- static char *argv[1];
++ static char *argv[2];
+ int tflags = 1;
+ if(np && nv_isattr(np,BLT_DCL))
+ tflags |= 2;
diff --git a/source/ap/ksh93/patches/ksh-20140929-safefd.patch b/source/ap/ksh93/patches/ksh-20140929-safefd.patch
new file mode 100644
index 000000000..80db20528
--- /dev/null
+++ b/source/ap/ksh93/patches/ksh-20140929-safefd.patch
@@ -0,0 +1,52 @@
+diff -up ksh-20120801/src/cmd/ksh93/include/io.h.safefd ksh-20120801/src/cmd/ksh93/include/io.h
+--- ksh-20120801/src/cmd/ksh93/include/io.h.safefd 2015-03-03 18:21:40.544732158 +0100
++++ ksh-20120801/src/cmd/ksh93/include/io.h 2015-03-03 18:22:16.284447849 +0100
+@@ -78,6 +78,7 @@ extern void sh_iorestore(Shell_t*,int,i
+ extern Sfio_t *sh_iostream(Shell_t*,int);
+ extern int sh_redirect(Shell_t*,struct ionod*,int);
+ extern void sh_iosave(Shell_t *, int,int,char*);
++extern int safefdnumber(Shell_t* shp, int sfd);
+ extern int sh_iovalidfd(Shell_t*, int);
+ extern int sh_inuse(Shell_t*, int);
+ extern void sh_iounsave(Shell_t*);
+diff -up ksh-20120801/src/cmd/ksh93/sh/io.c.safefd ksh-20120801/src/cmd/ksh93/sh/io.c
+--- ksh-20120801/src/cmd/ksh93/sh/io.c.safefd 2015-03-03 18:21:40.511732421 +0100
++++ ksh-20120801/src/cmd/ksh93/sh/io.c 2015-03-03 18:21:40.544732158 +0100
+@@ -1724,6 +1724,25 @@ void sh_iosave(Shell_t *shp, register in
+ }
+ }
+
++int safefdnumber(Shell_t* shp, int sfd)
++{
++ register int fd;
++
++ while(1)
++ {
++ for(fd=0; fd < shp->topfd; fd++)
++ {
++ if (filemap[fd].save_fd==sfd || filemap[fd].orig_fd==sfd || (fcntl(sfd, F_GETFD) != -1 || errno != EBADF))
++ {
++ sfd++;
++ continue;
++ }
++ }
++ break;
++ }
++ return sfd;
++}
++
+ /*
+ * close all saved file descriptors
+ */
+diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.safefd ksh-20120801/src/cmd/ksh93/sh/subshell.c
+--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.safefd 2015-03-03 18:21:40.531732261 +0100
++++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2015-03-03 18:21:40.544732158 +0100
+@@ -673,7 +673,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
+ }
+ if(iop && sffileno(iop)==1)
+ {
+- int fd=sfsetfd(iop,3);
++ int fd=sfsetfd(iop,safefdnumber(shp,3));
+ if(fd<0)
+ {
+ shp->toomany = 1;