import ksh-20120801-267.el8

c8-beta imports/c8-beta/ksh-20120801-267.el8
MSVSphere Packaging Team 11 months ago
commit f10d3fd26f

2
.gitignore vendored

@ -0,0 +1,2 @@
SOURCES/INIT.2012-08-01.tgz
SOURCES/ast-ksh.2012-08-01.tgz

@ -0,0 +1,2 @@
0b472a615db384fe707042baaa3347dc1aa1c81e SOURCES/INIT.2012-08-01.tgz
316428e9937806183a134aa1669dea40c3a73695 SOURCES/ast-ksh.2012-08-01.tgz

@ -0,0 +1,12 @@
# .kshrc
# Source global definitions
if [ -f /etc/kshrc ]; then
. /etc/kshrc
fi
# use emacs editing mode by default
set -o emacs
# User specific aliases and functions

@ -0,0 +1,102 @@
From 2075b2b96208ac8b989ca316dcdd674c3f488e2b Mon Sep 17 00:00:00 2001
From: Martijn Dekker <martijn@inlv.org>
Date: Thu, 28 Dec 2023 04:02:28 +0000
Subject: [PATCH] Subject: [PATCH] Fix crash on failure to trim ~/.sh_history
@vmihalko writes:
> We were able to reproduce an old issue mentioned in
> https://bugzilla.redhat.com/show_bug.cgi?id=1885399 using the
> latest version of ksh. The corresponding code has not changed
> much in the past few years.
>
> To provide further explanation, the problem arises when a user's
> .sh_history file grows to a size that triggers the hist_trim
> function, but the user lacks (after the creation of .sh_history)
> the necessary write permissions to their $HOME directory. As a
> result, ksh becomes stuck in a recursive loop between the
> sh_histinit(src/cmd/ksh93/edit/history.c#L203) function and the
> hist_trim(src/cmd/ksh93/edit/history.c#L417) function.
>
> Conditions for reproduction:
>
> 1. The size of the .sh_history file is larger than the HIST_MAX
> limit. (src/cmd/ksh93/edit/history.c, line 325)
> 2. .sh_history file has not been changed in the HIST_RECENT
> seconds (src/cmd/ksh93/edit/history.c, line 406)
> 3. The user does not have permission to write to the $HOME
> directory.
src/cmd/ksh93/edit/history.c: hist_trim():
- Print a warning and return if unlink(2) fails. The warning tells
the user to check the history file's parent directory is
writable. This is the best I realistically do for now, because
this function's basic method assumes a writable parent directory.
- The temp file fallback is deleted because it's fundamentally
flawed: it assumes the temp file is made on the same volume as
the history file and can simply be rename(2)'d in place. Even
on systems where this is the case, it doesn't appear to be
working correctly, but this is not worth looking into.
Resolves: https://github.com/ksh93/ksh/issues/695
---
src/cmd/ksh93/edit/history.c | 34 ++++------------------------------
1 file changed, 4 insertions(+), 30 deletions(-)
diff --git a/src/cmd/ksh93/edit/history.c b/src/cmd/ksh93/edit/history.c
index 1f6cd7c..0ed8e8a 100644
--- a/src/cmd/ksh93/edit/history.c
+++ b/src/cmd/ksh93/edit/history.c
@@ -461,34 +461,13 @@ static History_t* hist_trim(History_t *hp, int n)
register char *cp;
register int incmd=1, c=0;
register History_t *hist_new, *hist_old = hp;
- char *buff, *endbuff, *tmpname=0;
+ char *buff, *endbuff;
off_t oldp,newp;
struct stat statb;
- unlink(hist_old->histname);
- if(access(hist_old->histname,F_OK) >= 0)
+ if(unlink(hist_old->histname) < 0)
{
- /* The unlink can fail on windows 95 */
- int fd;
- char *last, *name=hist_old->histname;
- close(sffileno(hist_old->histfp));
- tmpname = (char*)malloc(strlen(name)+14);
- if(last = strrchr(name,'/'))
- {
- *last = 0;
- pathtmp(tmpname,name,"hist",NIL(int*));
- *last = '/';
- }
- else
- pathtmp(tmpname,".","hist",NIL(int*));
- if(rename(name,tmpname) < 0)
- {
- free(tmpname);
- tmpname = name;
- }
- fd = open(tmpname,O_RDONLY);
- sfsetfd(hist_old->histfp,fd);
- if(tmpname==name)
- tmpname = 0;
+ errormsg(SH_DICT,ERROR_warn(0),"cannot trim history file %s; make sure parent directory is writable",hist_old->histname);
+ return hist_ptr = hist_old;
}
hist_ptr = 0;
if(fstat(sffileno(hist_old->histfp),&statb)>=0)
@@ -543,11 +522,6 @@ static History_t* hist_trim(History_t *hp, int n)
}
hist_cancel(hist_new);
sfclose(hist_old->histfp);
- if(tmpname)
- {
- unlink(tmpname);
- free(tmpname);
- }
free((char*)hist_old);
return hist_ptr = hist_new;
}
--
2.42.0

@ -0,0 +1,11 @@
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)
- CMDLIST(mkdir)
CMDLIST(logname)
CMDLIST(cat)
CMDLIST(cmp)

@ -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

@ -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.

@ -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);

@ -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 .

@ -0,0 +1,68 @@
diff -up ksh-20120801/src/cmd/ksh93/tests/builtins.sh.fixregr ksh-20120801/src/cmd/ksh93/tests/builtins.sh
--- ksh-20120801/src/cmd/ksh93/tests/builtins.sh.fixregr 2012-07-16 17:23:56.000000000 +0200
+++ ksh-20120801/src/cmd/ksh93/tests/builtins.sh 2012-08-08 12:29:00.733243019 +0200
@@ -303,9 +303,9 @@ then err_exit "printf '%..*s' not workin
fi
[[ $(printf '%q\n') == '' ]] || err_exit 'printf "%q" with missing arguments'
# we won't get hit by the one second boundary twice, right?
-[[ $(printf '%T\n' now) == "$(date)" ]] ||
-[[ $(printf '%T\n' now) == "$(date)" ]] ||
-err_exit 'printf "%T" now'
+[[ $(printf '%T\n' now | sed 's/GMT/UTC/') == "$(date)" ]] ||
+[[ $(printf '%T\n' now | sed 's/GMT/UTC/') == "$(date)" ]] ||
+err_exit 'printf "%T" now = '"$(printf '%T\n' now) != $(date)"
behead()
{
read line
diff -up ksh-20120801/src/cmd/ksh93/tests/locale.sh.fixregr ksh-20120801/src/cmd/ksh93/tests/locale.sh
--- ksh-20120801/src/cmd/ksh93/tests/locale.sh.fixregr 2012-06-26 21:57:46.000000000 +0200
+++ ksh-20120801/src/cmd/ksh93/tests/locale.sh 2012-08-08 12:29:20.039405240 +0200
@@ -104,6 +104,7 @@ if (( $($SHELL -c $'export LC_ALL='$loca
then LC_ALL=$locale $SHELL -c b1=$'"\342\202\254\342\202\254\342\202\254\342\202\254w\342\202\254\342\202\254\342\202\254\342\202\254"; [[ ${b1:4:1} == w ]]' || err_exit 'multibyte ${var:offset:len} not working correctly'
fi
+locale=en_US.UTF-8
#$SHELL -c 'export LANG='$locale'; printf "\u[20ac]\u[20ac]" > $tmp/two_euro_chars.txt'
printf $'\342\202\254\342\202\254' > $tmp/two_euro_chars.txt
exp="6 2 6"
@@ -111,11 +112,11 @@ set -- $($SHELL -c "
unset LC_CTYPE
export LANG=$locale
export LC_ALL=C
- command wc -C < $tmp/two_euro_chars.txt
+ command wc -m < $tmp/two_euro_chars.txt
unset LC_ALL
- command wc -C < $tmp/two_euro_chars.txt
+ command wc -m < $tmp/two_euro_chars.txt
export LC_ALL=C
- command wc -C < $tmp/two_euro_chars.txt
+ command wc -m < $tmp/two_euro_chars.txt
")
got=$*
[[ $got == $exp ]] || err_exit "command wc LC_ALL default failed -- expected '$exp', got '$got'"
@@ -134,6 +135,8 @@ set -- $($SHELL -c "
got=$*
[[ $got == $exp ]] || err_exit "builtin wc LC_ALL default failed -- expected '$exp', got '$got'"
+locale=C_EU.UTF-8
+
# multibyte char straddling buffer boundary
{
@@ -190,6 +193,7 @@ do exp=$1
done
# setocale(LC_ALL,"") after setlocale() initialization
+locale=en_US.UTF-8
printf 'f1\357\274\240f2\n' > input1
printf 't2\357\274\240f1\n' > input2
@@ -336,7 +340,7 @@ then LC_ALL=en_US.UTF-8
[[ $(print -r -- "$x") == $'hello\u[20ac]\xee world' ]] || err_exit '%q with unicode and non-unicode not working'
if [[ $(whence od) ]]
then got='68 65 6c 6c 6f e2 82 ac ee 20 77 6f 72 6c 64 0a'
- [[ $(print -r -- "$x" | od -An -tx1) == "$got" ]] || err_exit "incorrect string from printf %q"
+ [[ $(print -r -- "$x" | od -An -tx1) =~ $got ]] || err_exit "incorrect string from printf %q"
fi
fi

@ -0,0 +1,22 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/io.c.orig ksh-20120801/src/cmd/ksh93/sh/io.c
--- ksh-20120801/src/cmd/ksh93/sh/io.c.orig 2015-08-12 11:35:36.882268954 -0300
+++ ksh-20120801/src/cmd/ksh93/sh/io.c 2015-08-12 11:44:06.324587019 -0300
@@ -2580,10 +2580,18 @@ int sh_fcntl(register int fd, int op, ..
if(newfd>=0) switch(op)
{
case F_DUPFD:
+#if F_dupfd_cloexec != F_DUPFD
+ case F_dupfd_cloexec:
+#endif
if(shp->fdstatus[fd] == IOCLOSE)
shp->fdstatus[fd] = 0;
if(newfd>=shp->gd->lim.open_max)
sh_iovalidfd(shp,newfd);
+#if F_dupfd_cloexec != F_DUPFD
+ if(op==F_dupfd_cloexec)
+ shp->fdstatus[newfd] = (shp->fdstatus[fd]|IOCLEX);
+ else
+#endif
shp->fdstatus[newfd] = (shp->fdstatus[fd]&~IOCLEX);
if(fdnotify)
(*fdnotify)(fd,newfd);

@ -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)
{

@ -0,0 +1,150 @@
diff --git a/src/lib/libast/Mamfile b/src/lib/libast/Mamfile
--- a/src/lib/libast/Mamfile
+++ b/src/lib/libast/Mamfile
@@ -535,7 +535,7 @@ done misc/findlib.h
done misc/fastfind.c
meta fastfind.o %.c>%.o misc/fastfind.c fastfind
prev misc/fastfind.c
-exec - ${CC} ${mam_cc_FLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} -I. -Icomp -Imisc -Iinclude -Istd -D_PACKAGE_ast -c misc/fastfind.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} -I. -Icomp -Imisc -Iinclude -Istd -D_PACKAGE_ast -c misc/fastfind.c
done fastfind.o generated
make hashalloc.o
make hash/hashalloc.c
@@ -1641,7 +1641,7 @@ done sfio/sfhdr.h
done port/mc.c
meta mc.o %.c>%.o port/mc.c mc
prev port/mc.c
-exec - ${CC} ${mam_cc_FLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${DEBUG+-DDEBUG=${DEBUG}} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c port/mc.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${DEBUG+-DDEBUG=${DEBUG}} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c port/mc.c
done mc.o generated
make base64.o
make string/base64.c
@@ -2349,7 +2349,7 @@ prev tmx.h implicit
done tm/tmxfmt.c
meta tmxfmt.o %.c>%.o tm/tmxfmt.c tmxfmt
prev tm/tmxfmt.c
-exec - ${CC} ${mam_cc_FLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmxfmt.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c tm/tmxfmt.c
done tmxfmt.o generated
make tmxgettime.o
make tm/tmxgettime.c
@@ -3011,7 +3011,7 @@ prev include/ast.h implicit
done comp/spawnveg.c
meta spawnveg.o %.c>%.o comp/spawnveg.c spawnveg
prev comp/spawnveg.c
-exec - ${CC} ${mam_cc_FLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/spawnveg.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} -I. -Icomp -Iinclude -Istd -D_PACKAGE_ast -c comp/spawnveg.c
done spawnveg.o generated
make vfork.o
make comp/vfork.c
@@ -3812,7 +3812,7 @@ prev regex/reglib.h implicit
done regex/regcomp.c
meta regcomp.o %.c>%.o regex/regcomp.c regcomp
prev regex/regcomp.c
-exec - ${CC} ${mam_cc_FLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} -I. -Icomp -Iport -Iregex -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c regex/regcomp.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} -I. -Icomp -Iport -Iregex -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c regex/regcomp.c
done regcomp.o generated
make regcache.o
make regex/regcache.c
@@ -4251,7 +4251,7 @@ prev sfio/sfhdr.h implicit
done sfio/sfprintf.c
meta sfprintf.o %.c>%.o sfio/sfprintf.c sfprintf
prev sfio/sfprintf.c
-exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS.FORCE} ${mam_cc_NOPROTECT} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfprintf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${CCFLAGS.FORCE} ${mam_cc_NOPROTECT} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfprintf.c
done sfprintf.o generated
make sfputd.o
make sfio/sfputd.c
@@ -4291,7 +4291,7 @@ prev sfio/sfhdr.h implicit
done sfio/sfrd.c
meta sfrd.o %.c>%.o sfio/sfrd.c sfrd
prev sfio/sfrd.c
-exec - ${CC} ${mam_cc_FLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${DEBUG+-DDEBUG=${DEBUG}} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfrd.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${DEBUG+-DDEBUG=${DEBUG}} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfrd.c
done sfrd.o generated
make sfread.o
make sfio/sfread.c
@@ -4315,7 +4315,7 @@ prev sfio/sfhdr.h implicit
done sfio/sfscanf.c
meta sfscanf.o %.c>%.o sfio/sfscanf.c sfscanf
prev sfio/sfscanf.c
-exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS.FORCE} ${mam_cc_NOPROTECT} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfscanf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${CCFLAGS.FORCE} ${mam_cc_NOPROTECT} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfscanf.c
done sfscanf.o generated
make sfseek.o
make sfio/sfseek.c
@@ -4331,7 +4331,7 @@ prev sfio/sfhdr.h implicit
done sfio/sfset.c
meta sfset.o %.c>%.o sfio/sfset.c sfset
prev sfio/sfset.c
-exec - ${CC} ${mam_cc_FLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${DEBUG+-DDEBUG=${DEBUG}} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfset.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${DEBUG+-DDEBUG=${DEBUG}} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfset.c
done sfset.o generated
make sfsetbuf.o
make sfio/sfsetbuf.c
@@ -4445,7 +4445,7 @@ prev sfio/sfhdr.h implicit
done sfio/sfvprintf.c
meta sfvprintf.o %.c>%.o sfio/sfvprintf.c sfvprintf
prev sfio/sfvprintf.c
-exec - ${CC} ${mam_cc_FLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${mam_cc_NOPROTECT} ${DEBUG+-DDEBUG=${DEBUG}} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfvprintf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${mam_cc_NOPROTECT} ${DEBUG+-DDEBUG=${DEBUG}} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfvprintf.c
done sfvprintf.o generated
make sfvscanf.o
make sfio/sfvscanf.c
@@ -4454,7 +4454,7 @@ prev sfio/sfhdr.h implicit
done sfio/sfvscanf.c
meta sfvscanf.o %.c>%.o sfio/sfvscanf.c sfvscanf
prev sfio/sfvscanf.c
-exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS.FORCE} ${mam_cc_NOPROTECT} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfvscanf.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${CCFLAGS.FORCE} ${mam_cc_NOPROTECT} -I. -Icomp -Iport -Isfio -Iinclude -Istd -I${INSTALLROOT}/include -D_PACKAGE_ast -c sfio/sfvscanf.c
done sfvscanf.o generated
make sfwr.o
make sfio/sfwr.c
diff --git a/src/lib/libast/string/strdup.c b/src/lib/libast/string/strdup.c
--- a/src/lib/libast/string/strdup.c
+++ b/src/lib/libast/string/strdup.c
@@ -50,18 +50,11 @@ __STDPP__directive pragma pp:nohide strdup
#define extern __EXPORT__
#endif
-#pragma GCC push_options
-#pragma GCC optimize ("O0")
-
-
extern char*
-strdup(register const char* s)
+_ast_strdup(const char* s)
{
register char* t;
register int n;
return (s && (t = oldof(0, char, n = strlen(s) + 1, 0))) ? (char*)memcpy(t, s, n) : (char*)0;
}
-
-#pragma GCC pop_options
-
diff --git a/src/lib/libcmd/Mamfile b/src/lib/libcmd/Mamfile
--- a/src/lib/libcmd/Mamfile
+++ b/src/lib/libcmd/Mamfile
@@ -611,7 +611,7 @@ make id.o
prev id.c
meta id.o %.c>%.o id.c id
prev id.c
-exec - ${CC} ${mam_cc_FLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} -I. -I${PACKAGE_ast_INCLUDE} -DERROR_CATALOG=\""libcmd"\" -D_BLD_cmd -D_PACKAGE_ast -DUSAGE_LICENSE=\""[-author?Glenn Fowler <gsf@research.att.com>][-author?David Korn <dgk@research.att.com>][-copyright?Copyright (c) 1992-2012 AT&T Intellectual Property][-license?http://www.eclipse.org/org/documents/epl-v10.html][--catalog?libcmd]"\" -c id.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} -I. -I${PACKAGE_ast_INCLUDE} -DERROR_CATALOG=\""libcmd"\" -D_BLD_cmd -D_PACKAGE_ast -DUSAGE_LICENSE=\""[-author?Glenn Fowler <gsf@research.att.com>][-author?David Korn <dgk@research.att.com>][-copyright?Copyright (c) 1992-2012 AT&T Intellectual Property][-license?http://www.eclipse.org/org/documents/epl-v10.html][--catalog?libcmd]"\" -c id.c
done id.o generated
make join.o
prev join.c
diff --git a/src/lib/libdll/Mamfile b/src/lib/libdll/Mamfile
index fbeea49..a392d55 100644
--- a/src/lib/libdll/Mamfile
+++ b/src/lib/libdll/Mamfile
@@ -259,7 +259,7 @@ prev ${PACKAGE_ast_INCLUDE}/ast.h implicit
done dllscan.c
meta dllscan.o %.c>%.o dllscan.c dllscan
prev dllscan.c
-exec - ${CC} ${mam_cc_FLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} -I. -I${PACKAGE_ast_INCLUDE} -D_BLD_dll -D_PACKAGE_ast -c dllscan.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} -I. -I${PACKAGE_ast_INCLUDE} -D_BLD_dll -D_PACKAGE_ast -c dllscan.c
done dllscan.o generated
make dllcheck.o
make dllcheck.c

@ -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);

@ -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

@ -0,0 +1,22 @@
diff -up ksh-20120801/src/lib/libast/string/strdup.c.badgcc ksh-20120801/src/lib/libast/string/strdup.c
--- ksh-20120801/src/lib/libast/string/strdup.c.badgcc 2012-05-21 15:04:46.000000000 +0200
+++ ksh-20120801/src/lib/libast/string/strdup.c 2015-06-17 10:12:52.693922581 +0200
@@ -50,11 +50,18 @@ __STDPP__directive pragma pp:nohide strd
#define extern __EXPORT__
#endif
+#pragma GCC push_options
+#pragma GCC optimize ("O0")
+
+
extern char*
strdup(register const char* s)
{
register char* t;
register int n;
return (s && (t = oldof(0, char, n = strlen(s) + 1, 0))) ? (char*)memcpy(t, s, n) : (char*)0;
}
+
+#pragma GCC pop_options
+

@ -0,0 +1,21 @@
diff --git a/src/cmd/ksh93/Mamfile b/src/cmd/ksh93/Mamfile
--- a/src/cmd/ksh93/Mamfile
+++ b/src/cmd/ksh93/Mamfile
@@ -1111,7 +1111,7 @@ prev include/defs.h implicit
done sh/trestore.c
meta trestore.o %.c>%.o sh/trestore.c trestore
prev sh/trestore.c
-exec - ${CC} ${mam_cc_FLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${SHOPT_BASH+-DSHOPT_BASH=${SHOPT_BASH}} ${SHOPT_SYSRC+-DSHOPT_SYSRC=${SHOPT_SYSRC}} ${SHOPT_ACCT+-DSHOPT_ACCT=${SHOPT_ACCT}} ${SHOPT_SPAWN+-DSHOPT_SPAWN=${SHOPT_SPAWN}} ${SH_CMDLIB_DIR+-DSH_CMDLIB_DIR=${SH_CMDLIB_DIR}} ${SH_DICT+-DSH_DICT=${SH_DICT}} ${SHOPT_P_SUID+-DSHOPT_P_SUID=${SHOPT_P_SUID}} ${SHOPT_REGRESS+-DSHOPT_REGRESS=${SHOPT_REGRESS}} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_BLD_shell -DKSHELL -D_API_ast=20100309 -D_PACKAGE_ast -DSHOPT_SUID_EXEC -DSHOPT_BRACEPAT -DSHOPT_STATS -DSHOPT_NAMESPACE -DSHOPT_COSHELL -DSHOPT_PFSH -DSHOPT_HISTEXPAND -DERROR_CONTEXT_T=Error_context_t -DSHOPT_FIXEDARRAY -DSHOPT_ESH -DSHOPT_MULTIBYTE -c sh/trestore.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${SHOPT_BASH+-DSHOPT_BASH=${SHOPT_BASH}} ${SHOPT_SYSRC+-DSHOPT_SYSRC=${SHOPT_SYSRC}} ${SHOPT_ACCT+-DSHOPT_ACCT=${SHOPT_ACCT}} ${SHOPT_SPAWN+-DSHOPT_SPAWN=${SHOPT_SPAWN}} ${SH_CMDLIB_DIR+-DSH_CMDLIB_DIR=${SH_CMDLIB_DIR}} ${SH_DICT+-DSH_DICT=${SH_DICT}} ${SHOPT_P_SUID+-DSHOPT_P_SUID=${SHOPT_P_SUID}} ${SHOPT_REGRESS+-DSHOPT_REGRESS=${SHOPT_REGRESS}} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_BLD_shell -DKSHELL -D_API_ast=20100309 -D_PACKAGE_ast -DSHOPT_SUID_EXEC -DSHOPT_BRACEPAT -DSHOPT_STATS -DSHOPT_NAMESPACE -DSHOPT_COSHELL -DSHOPT_PFSH -DSHOPT_HISTEXPAND -DERROR_CONTEXT_T=Error_context_t -DSHOPT_FIXEDARRAY -DSHOPT_ESH -DSHOPT_MULTIBYTE -c sh/trestore.c
done trestore.o generated
make waitevent.o
make sh/waitevent.c
@@ -1199,7 +1199,7 @@ prev ${PACKAGE_ast_INCLUDE}/ast_standards.h implicit
done data/strdata.c
meta strdata.o %.c>%.o data/strdata.c strdata
prev data/strdata.c
-exec - ${CC} ${mam_cc_FLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${SHOPT_BASH+-DSHOPT_BASH=${SHOPT_BASH}} ${SH_CMDLIB_DIR+-DSH_CMDLIB_DIR=${SH_CMDLIB_DIR}} ${SH_DICT+-DSH_DICT=${SH_DICT}} ${SHOPT_P_SUID+-DSHOPT_P_SUID=${SHOPT_P_SUID}} ${SHOPT_REGRESS+-DSHOPT_REGRESS=${SHOPT_REGRESS}} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -DSHOPT_STATS -DSHOPT_NAMESPACE -DSHOPT_COSHELL -DSHOPT_PFSH -DSHOPT_HISTEXPAND -D_BLD_shell -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -DSHOPT_FIXEDARRAY -DSHOPT_ESH -DSHOPT_MULTIBYTE -c data/strdata.c
+exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${-debug-symbols?1?${mam_cc_DEBUG} -D_BLD_DEBUG?${CCFLAGS.FORCE}?} ${SHOPT_BASH+-DSHOPT_BASH=${SHOPT_BASH}} ${SH_CMDLIB_DIR+-DSH_CMDLIB_DIR=${SH_CMDLIB_DIR}} ${SH_DICT+-DSH_DICT=${SH_DICT}} ${SHOPT_P_SUID+-DSHOPT_P_SUID=${SHOPT_P_SUID}} ${SHOPT_REGRESS+-DSHOPT_REGRESS=${SHOPT_REGRESS}} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -DSHOPT_STATS -DSHOPT_NAMESPACE -DSHOPT_COSHELL -DSHOPT_PFSH -DSHOPT_HISTEXPAND -D_BLD_shell -D_API_ast=20100309 -D_PACKAGE_ast -DERROR_CONTEXT_T=Error_context_t -DSHOPT_FIXEDARRAY -DSHOPT_ESH -DSHOPT_MULTIBYTE -c data/strdata.c
done strdata.o generated
make testops.o
make data/testops.c

@ -0,0 +1,14 @@
diff -up ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.cdfix ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c
--- ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.cdfix 2013-02-01 16:04:55.507150242 +0100
+++ ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c 2013-02-01 16:06:39.361007641 +0100
@@ -214,7 +214,10 @@ int b_cd(int argc, char *argv[],Shbltin_
if(*++dp=='.' && (*++dp=='/' || *dp==0))
n++;
else if(*dp && *dp!='/')
+ {
+ dp--;
break;
+ }
if(*dp==0)
break;
}

@ -0,0 +1,25 @@
diff -up ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.cdfix2 ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c
--- ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.cdfix2 2013-02-01 16:46:50.441771371 +0100
+++ ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c 2013-02-01 16:57:43.241784024 +0100
@@ -61,6 +61,7 @@ int sh_diropenat(Shell_t *shp, int dir,
{
int fd,shfd;
int savederrno=errno;
+ struct stat fs;
#ifndef AT_FDCWD
NOT_USED(dir);
#endif
@@ -133,6 +134,13 @@ int sh_diropenat(Shell_t *shp, int dir,
if(fd < 0)
return fd;
+
+ if (!fstat(fd, &fs) && !S_ISDIR(fs.st_mode))
+ {
+ close(fd);
+ errno = ENOTDIR;
+ return -1;
+ }
/* Move fd to a number > 10 and *register* the fd number with the shell */
shfd = sh_fcntl(fd, F_dupfd_cloexec, 10);

@ -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);

@ -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;

@ -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;
}
}

@ -0,0 +1,57 @@
diff --git a/src/cmd/ksh93/edit/edit.c b/src/cmd/ksh93/edit/edit.c
--- a/src/cmd/ksh93/edit/edit.c
+++ b/src/cmd/ksh93/edit/edit.c
@@ -46,6 +46,8 @@
extern char ed_errbuf[];
char e_version[] = "\n@(#)$Id: Editlib version 1993-12-28 r $\0\n";
#endif /* KSHELL */
+
+#include <sys/ioctl.h>
#include "io.h"
#include "terminal.h"
#include "history.h"
diff --git a/src/cmd/ksh93/include/defs.h b/src/cmd/ksh93/include/defs.h
--- a/src/cmd/ksh93/include/defs.h
+++ b/src/cmd/ksh93/include/defs.h
@@ -449,6 +449,8 @@ extern int sh_whence(char**,int);
extern Namval_t *sh_fsearch(Shell_t*,const char *,int);
#endif /* SHOPT_NAMESPACE */
+extern int sh_diropenat(Shell_t *, int, const char *, bool xattr);
+
#ifndef ERROR_dictionary
# define ERROR_dictionary(s) (s)
#endif
diff --git a/src/lib/libast/port/astwinsize.c b/src/lib/libast/port/astwinsize.c
--- a/src/lib/libast/port/astwinsize.c
+++ b/src/lib/libast/port/astwinsize.c
@@ -28,6 +28,7 @@
#include <ast.h>
#include <ast_tty.h>
+#include <sys/ioctl.h>
#if defined(__STDPP__directive) && defined(__STDPP__hide)
__STDPP__directive pragma pp:hide ioctl sleep
@@ -36,10 +37,6 @@ __STDPP__directive pragma pp:hide ioctl sleep
#define sleep ______sleep
#endif
-#if _sys_ioctl
-#include <sys/ioctl.h>
-#endif
-
#if defined(TIOCGWINSZ)
#if _sys_stream && _sys_ptem
#include <sys/stream.h>
diff --git a/src/lib/libcmd/tail.c b/src/lib/libcmd/tail.c
--- a/src/lib/libcmd/tail.c
+++ b/src/lib/libcmd/tail.c
@@ -104,6 +104,7 @@ USAGE_LICENSE
#include <ls.h>
#include <tv.h>
#include <rev.h>
+#include <time.h>
#define COUNT (1<<0)
#define ERROR (1<<1)

@ -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-22 11:48:57.205062905 +0200
+++ ksh-20120801/src/cmd/ksh93/include/jobs.h 2014-07-22 11:48:57.243062711 +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-22 11:48:57.190062982 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/jobs.c 2014-07-22 11:48:57.243062711 +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-22 11:48:57.234062758 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2014-07-22 11:54:04.164491483 +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;
if(comsub!=1 && shp->spid)
{
job_wait(shp->spid);
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-22 11:48:57.228062787 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2014-07-22 11:48:57.245062700 +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

@ -0,0 +1,52 @@
diff --git a/src/cmd/ksh93/sh/arith.c b/src/cmd/ksh93/sh/arith.c
--- a/src/cmd/ksh93/sh/arith.c
+++ b/src/cmd/ksh93/sh/arith.c
@@ -513,21 +513,34 @@ Sfdouble_t sh_strnum(register const char *str, char** ptr, int mode)
char base=(shp->inarith?0:10), *last;
if(*str==0)
{
- if(ptr)
- *ptr = (char*)str;
- return(0);
- }
- errno = 0;
- d = strtonll(str,&last,&base,-1);
- if(*last || errno)
- {
- if(!last || *last!='.' || last[1]!='.')
- d = strval(shp,str,&last,arith,mode);
- if(!ptr && *last && mode>0)
- errormsg(SH_DICT,ERROR_exit(1),e_lexbadchar,*last,str);
+ d = 0.0;
+ last = (char*)str;
+ } else {
+ errno = 0;
+ d = strtonll(str,&last,&base,-1);
+ if (*last && !shp->inarith && sh_isstate(SH_INIT)) {
+ // This call is to handle "base#value" literals if we're importing untrusted env vars.
+ errno = 0;
+ d = strtonll(str, &last, NULL, -1);
+ }
+
+ if(*last || errno)
+ {
+ if (sh_isstate(SH_INIT)) {
+ // Initializing means importing untrusted env vars. Since the string does not appear
+ // to be a recognized numeric literal give up. We can't safely call strval() since
+ // that allows arbitrary expressions which would create a security vulnerability.
+ d = 0.0;
+ } else {
+ if(!last || *last!='.' || last[1]!='.')
+ d = strval(shp,str,&last,arith,mode);
+ if(!ptr && *last && mode>0)
+ errormsg(SH_DICT,ERROR_exit(1),e_lexbadchar,*last,str);
+ }
+ } else if (!d && *str=='-') {
+ d = -0.0;
+ }
}
- else if (!d && *str=='-')
- d = -0.0;
if(ptr)
*ptr = last;
return(d);

@ -0,0 +1,19 @@
diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c
index 1ba7347..ab745d4 100644
--- a/src/cmd/ksh93/sh/xec.c
+++ b/src/cmd/ksh93/sh/xec.c
@@ -640,7 +640,11 @@ int sh_eval(register Sfio_t *iop, int mode)
if(lineno)
shp->inlineno = lineno;
if(io_save)
+ {
sfclose(io_save);
+ io_save = 0;
+ }
+
sh_freeup(shp);
shp->st.staklist = saveslp;
shp->fn_reset = 0;
--
2.9.3

@ -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)

@ -0,0 +1,72 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/macro.c.fd2lost ksh-20120801/src/cmd/ksh93/sh/macro.c
--- ksh-20120801/src/cmd/ksh93/sh/macro.c.fd2lost 2014-01-22 16:23:21.211658984 +0100
+++ ksh-20120801/src/cmd/ksh93/sh/macro.c 2014-01-22 16:23:21.243658703 +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;
diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.fd2lost ksh-20120801/src/cmd/ksh93/sh/subshell.c
--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.fd2lost 2014-01-22 16:23:21.222658887 +0100
+++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2014-01-22 16:23:21.243658703 +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 */
@@ -635,6 +636,13 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
}
else
{
+ if(comsub!=1 && shp->spid)
+ {
+ job_wait(shp->spid);
+ if(shp->pipepid==shp->spid)
+ shp->spid = 0;
+ shp->pipepid = 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.fd2lost ksh-20120801/src/cmd/ksh93/sh/xec.c
--- ksh-20120801/src/cmd/ksh93/sh/xec.c.fd2lost 2014-01-22 16:23:21.237658756 +0100
+++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2014-01-22 16:38:36.374666019 +0100
@@ -1756,6 +1756,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))
@@ -1771,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)

@ -0,0 +1,11 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/io.c.tryfix01 ksh-20120801/src/cmd/ksh93/sh/io.c
--- ksh-20120801/src/cmd/ksh93/sh/io.c.tryfix01 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);

@ -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;

@ -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;
}
/*

@ -0,0 +1,38 @@
diff --git a/src/lib/libast/features/stdio b/src/lib/libast/features/stdio
--- a/src/lib/libast/features/stdio
+++ b/src/lib/libast/features/stdio
@@ -6,6 +6,8 @@ cat{
#define _FILE_DEFINED 1
#define _FILE_defined 1
#define _FILEDEFED 1
+ #define __FILE_defined 1
+ #define ____FILE_defined 1
#ifndef __FILE_TAG
#define __FILE_TAG _sfio_s
diff --git a/src/lib/libast/include/ast.h b/src/lib/libast/include/ast.h
index ebf82d7..f4bbe6d 100644
--- a/src/lib/libast/include/ast.h
+++ b/src/lib/libast/include/ast.h
@@ -59,9 +59,21 @@ struct _sfio_s;
#ifndef __FILE_typedef
#define __FILE_typedef 1
#endif
+#ifndef _FILE_DEFINED
+#define _FILE_DEFINED 1
+#endif
+#ifndef _FILE_defined
+#define _FILE_defined 1
+#endif
#ifndef _FILEDEFED
#define _FILEDEFED 1
#endif
+#ifndef __FILE_defined
+#define __FILE_defined 1
+#endif
+#ifndef ____FILE_defined
+#define ____FILE_defined 1
+#endif
#endif
/*

@ -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 */

@ -0,0 +1,74 @@
diff --git a/src/cmd/ksh93/sh/fcin.c b/src/cmd/ksh93/sh/fcin.c
index ea6ea6b..08c1f2a 100644
--- a/src/cmd/ksh93/sh/fcin.c
+++ b/src/cmd/ksh93/sh/fcin.c
@@ -150,63 +150,19 @@ extern void fcrestore(Fcin_t *fp)
_Fcin = *fp;
}
-/* for testing purposes with small buffers */
-#if defined(IOBSIZE) && (IOBSIZE < 2*MB_LEN_MAX)
-# undef MB_LEN_MAX
-# define MB_LEN_MAX (IOBSIZE/2)
-#endif
-
-struct Extra
-{
- unsigned char buff[2*MB_LEN_MAX];
- unsigned char *next;
-};
-
int _fcmbget(short *len)
{
- static struct Extra extra;
- register int i, c, n;
- if(_Fcin.fcleft)
- {
- if((c = mbsize(extra.next)) < 0)
- c = 1;
- if((_Fcin.fcleft -= c) <=0)
- {
- _Fcin.fcptr = (unsigned char*)fcfirst() - _Fcin.fcleft;
- _Fcin.fcleft = 0;
- }
- *len = c;
- if(c==1)
- c = *extra.next++;
- else if(c==0)
- _Fcin.fcleft = 0;
- else
- c = mbchar(extra.next);
- return(c);
- }
- switch(*len = mbsize(_Fcin.fcptr))
+ register int c;
+ switch (*len = mbsize(_Fcin.fcptr))
{
- case -1:
- if(_Fcin._fcfile && (n=(_Fcin.fclast-_Fcin.fcptr)) < MB_LEN_MAX)
- {
- memcpy(extra.buff, _Fcin.fcptr, n);
- _Fcin.fcptr = _Fcin.fclast;
- for(i=n; i < MB_LEN_MAX+n; i++)
- {
- if((extra.buff[i] = fcgetc(c))==0)
- break;
- }
- _Fcin.fcleft = n;
- extra.next = extra.buff;
- return(fcmbget(len));
- }
+ case -1:
*len = 1;
/* fall through */
- case 0:
- case 1:
+ case 0:
+ case 1:
c=fcget();
break;
- default:
+ default:
c = mbchar(_Fcin.fcptr);
}
return(c);

@ -0,0 +1,47 @@
From 27909acb584aed231d757d1d63c6c62b57c8e152 Mon Sep 17 00:00:00 2001
From: Vincent Mihalkovic <vmihalko@redhat.com>
Date: Mon, 3 Jan 2022 14:03:20 +0100
Subject: [PATCH] Fix race conditions running external commands with job
control on
When ksh is compiled with SHOPT_SPAWN (the default), which uses
posix_spawn(3) or vfork(2) (via sh_ntfork()) to launch external
commands, at least two race conditions occur when launching
external commands while job control is active. See:
https://bugs.launchpad.net/ubuntu/+source/ksh/+bug/1887863/comments/3
https://www.mail-archive.com/ast-developers@research.att.com/msg00717.html
The basic issue is that this performance optimisation is
incompatible with job control, because it uses a spawning mechanism
that doesn't copy the parent process' memory pages into the child
process, therefore no state that involves memory can be set before
exec-ing the external program. This makes it impossible to
correctly set the terminal's process group ID in the child process,
something that is essential for job control to work.
src/cmd/ksh93/sh/xec.c:
- Use sh_fork() instead of sh_ntfork() if job control is active.
This uses fork(2), which is 30%-ish slower on most sytems, but
allows for correctly setting the terminal process group.
Fixes: https://github.com/ksh93/ksh/issues/79
---
src/cmd/ksh93/sh/xec.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c
index ae13178..be57a6b 100644
--- a/src/cmd/ksh93/sh/xec.c
+++ b/src/cmd/ksh93/sh/xec.c
@@ -1737,7 +1737,7 @@ int sh_exec(register const Shnode_t *t, int flags)
#else
#if SHOPT_SPAWN
# ifdef _lib_fork
- if(com)
+ if(com && !job.jobcontrol)
parent = sh_ntfork(shp,t,com,&jobid,ntflag);
else
parent = sh_fork(shp,type,&jobid);
--
2.31.1

@ -0,0 +1,11 @@
diff --git a/src/cmd/ksh93/sh/jobs.c b/src/cmd/ksh93/sh/jobs.c
--- a/src/cmd/ksh93/sh/jobs.c
+++ b/src/cmd/ksh93/sh/jobs.c
@@ -1579,6 +1579,7 @@ int job_wait(register pid_t pid)
if( pw->p_exit!=SIGTTIN && pw->p_exit!=SIGTTOU)
break;
+ tcsetpgrp(JOBTTY,pw->p_pgrp);
killpg(pw->p_pgrp,SIGCONT);
}
else /* ignore stop when non-interactive */

@ -0,0 +1,12 @@
diff --git a/src/cmd/ksh93/sh/parse.c b/src/cmd/ksh93/sh/parse.c
index d139389..5a02af7 100644
--- a/src/cmd/ksh93/sh/parse.c
+++ b/src/cmd/ksh93/sh/parse.c
@@ -2032,6 +2032,7 @@ unsigned long kiaentity(Lex_t *lexp,const char *name,int len,int type,int first,
else
sfputr(stkp,name,0);
}
+ sfputc(stkp,'\0');
np = nv_search(stakptr(offset),lexp->entity_tree,NV_ADD);
stkseek(stkp,offset);
np->nvalue.i = pkind;

@ -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])

@ -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;

@ -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)

@ -0,0 +1,178 @@
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

@ -0,0 +1,15 @@
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 2015-08-24 14:29:58.602967855 -0300
+++ ksh-20120801/src/cmd/ksh93/sh/macro.c 2015-08-24 14:31:13.682850008 -0300
@@ -1479,7 +1479,10 @@ retry1:
default:
goto nosub;
}
- c = fcmbget(&LEN);
+ if(type)
+ c = fcmbget(&LEN);
+ else
+ c = fcget();
if(type>M_TREE)
{
if(c!=RBRACE)

@ -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))

@ -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);

@ -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 */

@ -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)

@ -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);
}
}

@ -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 */

@ -0,0 +1,12 @@
diff --git a/src/cmd/ksh93/sh/name.c b/src/cmd/ksh93/sh/name.c
--- a/src/cmd/ksh93/sh/name.c
+++ b/src/cmd/ksh93/sh/name.c
@@ -1425,7 +1425,7 @@ Namval_t *nv_open(const char *name, Dt_t *root, int flags)
{
if(xp->root!=root)
continue;
- if(*name==*xp->name && xp->namespace==shp->namespace && (flags&(NV_ARRAY|NV_NOSCOPE))==xp->flags && memcmp(xp->name,name,xp->len)==0 && (name[xp->len]==0 || name[xp->len]=='=' || name[xp->len]=='+'))
+ if(*name==*xp->name && xp->namespace==shp->namespace && (flags&(NV_ARRAY|NV_NOSCOPE))==xp->flags && strncmp(xp->name,name,xp->len)==0 && (name[xp->len]==0 || name[xp->len]=='=' || name[xp->len]=='+'))
{
sh_stats(STAT_NVHITS);
np = xp->np;

@ -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;

@ -0,0 +1,26 @@
--- ksh_20120801/src/cmd/ksh93/sh/lex.c 2012-06-12 21:05:18.000000000 +0200
+++ ksh_20120801/src/cmd/ksh93/sh/lex.c 2015-08-18 17:42:06.138076565 +0200
@@ -1603,7 +1603,14 @@ static int comsub(register Lex_t *lp, in
if(n==4)
break;
if(sh_lexstates[ST_NAME][c])
+ {
+ if(c==' ' || c=='\t')
+ {
+ n = 0;
+ continue;
+ }
goto skip;
+ }
word[n++] = c;
}
if(sh_lexstates[ST_NAME][c]==S_BREAK)
--- ksh_20120801/src/cmd/ksh93/tests/subshell.sh 2012-07-25 23:40:29.000000000 +0200
+++ ksh_20120801/src/cmd/ksh93/tests/subshell.sh 2015-08-18 17:42:06.143076553 +0200
@@ -617,4 +617,6 @@ do if [[ -e $f ]]
fi
done
+$SHELL > /dev/null -c 'echo $(for x in whatever; do case y in *) true;; esac; done)' || err_exit 'syntax error with case in command substitution'
+
exit $((Errors<125?Errors:125))

@ -0,0 +1,24 @@
diff --git a/src/cmd/ksh93/sh/fault.c b/src/cmd/ksh93/sh/fault.c
--- a/src/cmd/ksh93/sh/fault.c
+++ b/src/cmd/ksh93/sh/fault.c
@@ -643,7 +643,7 @@ void sh_done(void *ptr, register int sig)
sfsync((Sfio_t*)sfstdin);
sfsync((Sfio_t*)shp->outpool);
sfsync((Sfio_t*)sfstdout);
- if(savxit&SH_EXITSIG)
+ if((savxit&SH_EXITMASK) == shp->lastsig)
sig = savxit&SH_EXITMASK;
if(sig)
{
@@ -668,6 +668,12 @@ void sh_done(void *ptr, register int sig)
if(sh_isoption(SH_NOEXEC))
kiaclose((Lex_t*)shp->lex_context);
#endif /* SHOPT_KIA */
+
+ /* Return POSIX exit code if last process exits due to signal */
+ if (savxit & SH_EXITSIG) {
+ exit(128 + (savxit&SH_EXITMASK));
+ }
+
exit(savxit&SH_EXITMASK);
}

@ -0,0 +1,14 @@
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-10-01 17:34:47.720532950 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2014-10-01 17:35:25.850350378 +0200
@@ -655,7 +655,10 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
job.hack1_waitall=0;
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;

@ -0,0 +1,505 @@
diff -up ksh20120801/src/cmd/ksh93/sh/subshell.c.orig ksh20120801/src/cmd/ksh93/sh/subshell.c
--- ksh20120801/src/cmd/ksh93/sh/subshell.c.orig 2012-07-17 23:54:21.000000000 +0200
+++ ksh20120801/src/cmd/ksh93/sh/subshell.c 2012-10-24 15:03:44.436870792 +0200
@@ -40,14 +40,6 @@
# define PIPE_BUF 512
#endif
-#ifndef O_SEARCH
-# ifdef O_PATH
-# define O_SEARCH O_PATH
-# else
-# define O_SEARCH 0
-# endif
-#endif
-
/*
* Note that the following structure must be the same
* size as the Dtlink_t structure
@@ -84,7 +76,7 @@ static struct subshell
char *pwd; /* present working directory */
const char *shpwd; /* saved pointer to sh.pwd */
void *jobs; /* save job info */
- int pwdfd; /* file descritor for pwd */
+ int shpwdfd;/* fd for present working directory */
mode_t mask; /* saved umask */
short tmpfd; /* saved tmp file descriptor */
short pipefd; /* read fd if pipe is created */
@@ -101,7 +93,6 @@ static struct subshell
int subdup;
char subshare;
char comsub;
- char pwdclose;
#if SHOPT_COSHELL
void *coshell;
#endif /* SHOPT_COSHELL */
@@ -518,7 +509,6 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
shp->pathinit = 0;
}
sp->pathlist = path_dup((Pathcomp_t*)shp->pathlist);
- sp->pwdfd = -1;
if(!shp->pwd)
path_pwd(shp,0);
sp->bckpid = shp->bckpid;
@@ -531,39 +521,14 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
shp->subshare = comsub==2 || (comsub==1 && sh_isoption(SH_SUBSHARE));
if(comsub)
shp->comsub = comsub;
+ sp->shpwdfd=-1;
if(!comsub || !shp->subshare)
{
- struct subshell *xp;
sp->shpwd = shp->pwd;
-#ifdef _lib_fchdir
- for(xp=sp->prev; xp; xp=xp->prev)
- {
- if(xp->pwdfd>0 && strcmp(xp->pwd,shp->pwd)==0)
- {
- sp->pwdfd = xp->pwdfd;
- break;
- }
- }
- if(sp->pwdfd<0)
- {
- int n = open(".",O_RDONLY);
- if(O_SEARCH && errno==EACCES)
- n = open(".",O_RDONLY);
- if(n>=0)
- {
- sp->pwdfd = n;
- if(n<10)
- {
- sp->pwdfd = sh_fcntl(n,F_DUPFD,10);
- close(n);
- }
- if(sp->pwdfd>0)
- {
- fcntl(sp->pwdfd,F_SETFD,FD_CLOEXEC);
- sp->pwdclose = 1;
- }
- }
- }
+ sp->shpwdfd=((shp->pwdfd >= 0))?sh_fcntl(shp->pwdfd, F_dupfd_cloexec, 10):-1;
+#ifdef O_SEARCH
+ if(sp->shpwdfd<0)
+ errormsg(SH_DICT,ERROR_system(1), "Can't obtain directory fd.");
#endif
sp->pwd = (shp->pwd?strdup(shp->pwd):0);
sp->mask = shp->mask;
@@ -741,14 +706,11 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
Namval_t *pwdnod = sh_scoped(shp,PWDNOD);
if(shp->pwd)
{
- if(sp->pwdfd >=0)
- {
- if(fchdir(sp->pwdfd)<0)
- chdir(sp->pwd);
- }
- else
- chdir(sp->pwd);
shp->pwd=sp->pwd;
+#ifndef O_SEARCH
+ if (sp->shpwdfd < 0)
+ chdir(shp->pwd);
+#endif
path_newdir(shp,shp->pathlist);
}
if(nv_isattr(pwdnod,NV_NOFREE))
@@ -762,8 +724,6 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
}
else
free((void*)sp->pwd);
- if(sp->pwdclose)
- close(sp->pwdfd);
if(sp->mask!=shp->mask)
umask(shp->mask=sp->mask);
if(shp->coutpipe!=sp->coutpipe)
@@ -775,6 +735,13 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
shp->cpipe[1] = sp->cpipe;
shp->coutpipe = sp->coutpipe;
}
+ if(sp->shpwdfd >=0)
+ {
+ if(shp->pwdfd >=0)
+ sh_close(shp->pwdfd);
+ shp->pwdfd=sp->shpwdfd;
+ fchdir(shp->pwdfd);
+ }
shp->subshare = sp->subshare;
shp->comsub = sp->comsub;
shp->subdup = sp->subdup;
diff -up ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.orig ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c
--- ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.orig 2012-08-02 16:50:40.000000000 +0200
+++ ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c 2012-10-24 15:37:46.814469045 +0200
@@ -38,6 +38,10 @@
#include "builtins.h"
#include <ls.h>
+#ifndef EINTR_REPEAT
+# define EINTR_REPEAT(expr) while((expr) && (errno == EINTR)) errno=0;
+#endif
+
/*
* Invalidate path name bindings to relative paths
*/
@@ -49,6 +53,95 @@ static void rehash(register Namval_t *np
_nv_unset(np,0);
}
+/*
+ * Obtain a file handle to the directory "path" relative to directory
+ * "dir", or open a NFSv4 xattr directory handle for file dir/path.
+ */
+int sh_diropenat(Shell_t *shp, int dir, const char *path, bool xattr)
+{
+ int fd,shfd;
+ int savederrno=errno;
+#ifndef AT_FDCWD
+ NOT_USED(dir);
+#endif
+#ifndef O_XATTR
+ NOT_USED(xattr);
+#endif
+
+#ifdef O_XATTR
+ if(xattr)
+ {
+ int apfd; /* attribute parent fd */
+ /* open parent node... */
+ EINTR_REPEAT((apfd = openat(dir, path, O_RDONLY|O_NONBLOCK|O_cloexec)) < 0);
+ if(apfd < 0)
+ return -1;
+
+ /* ... and then open a fd to the attribute directory */
+ EINTR_REPEAT((fd = openat(apfd, e_dot, O_XATTR|O_cloexec)) < 0);
+
+ savederrno = errno;
+ EINTR_REPEAT(close(apfd) < 0);
+ errno = savederrno;
+ }
+ else
+#endif
+ {
+#ifdef AT_FDCWD
+ /*
+ * Open directory. First we try without |O_SEARCH| and
+ * if this fails with EACCESS we try with |O_SEARCH|
+ * again.
+ * This is required ...
+ * - ... because some platforms may require that it can
+ * only be used for directories while some filesystems
+ * (e.g. Reiser4 or HSM systems) allow a |fchdir()| into
+ * files, too)
+ * - ... to preserve the semantics of "cd", e.g.
+ * otherwise "cd" would return [No access] instead of
+ * [Not a directory] for files on filesystems which do
+ * not allow a "cd" into files.
+ * - ... to allow that a
+ * $ redirect {n}</etc ; cd /dev/fd/$n # works on most
+ * platforms.
+ */
+ EINTR_REPEAT((fd = openat(dir, path, O_RDONLY|O_NONBLOCK|O_cloexec)) < 0);
+# ifdef O_SEARCH
+ if((fd < 0) && (errno == EACCES))
+ {
+ EINTR_REPEAT((fd = openat(dir, path, O_SEARCH|O_cloexec)) < 0)
+ }
+# endif
+#else
+ /*
+ * Version of openat() call above for systems without
+ * openat API. This only works because we basically
+ * gurantee that |dir| is always the same place as
+ * |cwd| on such machines (but this won't be the case
+ * in the future).
+ */
+ /*
+ * This |fchdir()| call is not needed (yet) since
+ * all consumers do not use |dir| when |AT_FDCWD|
+ * is not available.
+ *
+ * fchdir(dir);
+ */
+ EINTR_REPEAT((fd = open(path, O_cloexec)) < 0);
+#endif
+ }
+
+ if(fd < 0)
+ return fd;
+
+ /* Move fd to a number > 10 and *register* the fd number with the shell */
+ shfd = sh_fcntl(fd, F_dupfd_cloexec, 10);
+ savederrno=errno;
+ sh_close(fd);
+ errno=savederrno;
+ return(shfd);
+}
+
int b_cd(int argc, char *argv[],Shbltin_t *context)
{
register char *dir;
@@ -56,18 +149,20 @@ int b_cd(int argc, char *argv[],Shbltin_
register const char *dp;
register Shell_t *shp = context->shp;
int saverrno=0;
- int rval,flag=0;
+ int rval;
+ bool flag=false,xattr=false;
char *oldpwd;
+ int newdirfd;
Namval_t *opwdnod, *pwdnod;
if(sh_isoption(SH_RESTRICTED))
errormsg(SH_DICT,ERROR_exit(1),e_restricted+4);
while((rval = optget(argv,sh_optcd))) switch(rval)
{
case 'L':
- flag = 0;
+ flag = false;
break;
case 'P':
- flag = 1;
+ flag = true;
break;
case ':':
errormsg(SH_DICT,2, "%s", opt_info.arg);
@@ -179,14 +274,72 @@ int b_cd(int argc, char *argv[],Shbltin_
continue;
#endif /* SHOPT_FS_3D */
}
+ rval = newdirfd = sh_diropenat(shp, shp->pwdfd,
+ path_relative(shp,stakptr(PATH_OFFSET)), xattr);
+ if(newdirfd >=0)
+ {
+ /* chdir for directories on HSM/tapeworms may take minutes */
+ if(fchdir(newdirfd) >= 0)
+ {
+ if(shp->pwdfd >= 0)
+ sh_close(shp->pwdfd);
+ shp->pwdfd=newdirfd;
+ goto success;
+ }
+ }
+#ifndef O_SEARCH
+ else
+ {
if((rval=chdir(path_relative(shp,stakptr(PATH_OFFSET)))) >= 0)
- goto success;
- if(errno!=ENOENT && saverrno==0)
+ {
+ if(shp->pwdfd >= 0)
+ {
+ sh_close(shp->pwdfd);
+#ifdef AT_FDCWD
+ shp->pwdfd = AT_FDCWD;
+#else
+ shp->pwdfd = -1;
+#endif
+ }
+ }
+ }
+#endif
+ if(saverrno==0)
saverrno=errno;
+ if(newdirfd >=0)
+ sh_close(newdirfd);
}
while(cdpath);
if(rval<0 && *dir=='/' && *(path_relative(shp,stakptr(PATH_OFFSET)))!='/')
- rval = chdir(dir);
+ {
+ rval = newdirfd = sh_diropenat(shp,
+ shp->pwdfd,
+ dir, xattr);
+ if(newdirfd >=0)
+ {
+ /* chdir for directories on HSM/tapeworms may take minutes */
+ if(fchdir(newdirfd) >= 0)
+ {
+ if(shp->pwdfd >= 0)
+ sh_close(shp->pwdfd);
+ shp->pwdfd=newdirfd;
+ goto success;
+ }
+ }
+#ifndef O_SEARCH
+ else
+ {
+ if(chdir(dir) >=0)
+ {
+ if(shp->pwdfd >= 0)
+ {
+ sh_close(shp->pwdfd);
+ shp->pwdfd=-1;
+ }
+ }
+ }
+#endif
+ }
/* use absolute chdir() if relative chdir() fails */
if(rval<0)
{
@@ -213,7 +366,7 @@ success:
if(*dir != '/')
return(0);
nv_putval(opwdnod,oldpwd,NV_RDONLY);
- flag = strlen(dir);
+ flag = (strlen(dir)>0)?true:false;
/* delete trailing '/' */
while(--flag>0 && dir[flag]=='/')
dir[flag] = 0;
diff -up ksh-20120801/src/cmd/ksh93/include/shell.h.orig ksh-20120801/src/cmd/ksh93/include/shell.h
--- ksh-20120801/src/cmd/ksh93/include/shell.h.orig 2012-07-17 22:07:40.000000000 +0200
+++ ksh-20120801/src/cmd/ksh93/include/shell.h 2012-10-24 15:42:10.756987230 +0200
@@ -145,6 +145,7 @@ struct Shell_s
unsigned char trapnote; /* set when trap/signal is pending */
char shcomp; /* set when runing shcomp */
short subshell; /* set for virtual subshell */
+ int pwdfd; /* file descriptor for pwd */
#ifdef _SH_PRIVATE
_SH_PRIVATE
#endif /* _SH_PRIVATE */
diff -up ksh-20120801/src/cmd/ksh93/sh/init.c.orig ksh-20120801/src/cmd/ksh93/sh/init.c
--- ksh-20120801/src/cmd/ksh93/sh/init.c.orig 2012-05-11 19:19:10.000000000 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/init.c 2012-10-24 15:31:59.659485151 +0200
@@ -1365,6 +1365,18 @@ Shell_t *sh_init(register int argc,regis
}
}
sh_ioinit(shp);
+#ifdef AT_FDCWD
+ shp->pwdfd = sh_diropenat(shp, AT_FDCWD, e_dot, false);
+#else
+ /* Systems without AT_FDCWD/openat() do not use the |dir| argument */
+ shp->pwdfd = sh_diropenat(shp, -1, e_dot, false);
+#endif
+#ifdef O_SEARCH
+ /* This should _never_ happen, guranteed by design and goat sacrifice */
+ if(shp->pwdfd < 0)
+ errormsg(SH_DICT,ERROR_system(1), "Can't obtain directory fd.");
+#endif
+
/* initialize signal handling */
sh_siginit(shp);
stakinstall(NIL(Stak_t*),nospace);
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 2012-07-23 16:49:32.000000000 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2012-10-24 15:35:02.209539671 +0200
@@ -1348,8 +1348,12 @@ int sh_exec(register const Shnode_t *t,
{
if(!shp->pwd)
path_pwd(shp,0);
- if(shp->pwd)
- stat(".",&statb);
+#ifndef O_SEARCH
+ else if (shp->pwdfd>=0)
+ fstat(shp->pwdfd,&statb);
+ else if (shp->pwd)
+ stat(e_dot,&statb);
+#endif
sfsync(NULL);
share = sfset(sfstdin,SF_SHARE,0);
sh_onstate(SH_STOPOK);
@@ -1428,14 +1432,32 @@ int sh_exec(register const Shnode_t *t,
sh_offstate(SH_NOFORK);
if(!(nv_isattr(np,BLT_ENV)))
{
- if(shp->pwd)
+#ifdef O_SEARCH
+ while((fchdir(shp->pwdfd) < 0) && errno==EINTR)
+ errno = 0;
+#else
+ if(shp->pwd || (shp->pwdfd >= 0))
{
struct stat stata;
stat(".",&stata);
/* restore directory changed */
if(statb.st_ino!=stata.st_ino || statb.st_dev!=stata.st_dev)
- chdir(shp->pwd);
+ {
+ /* chdir for directories on HSM/tapeworms may take minutes */
+ int err=errno;
+ if(shp->pwdfd >= 0)
+ {
+ while((fchdir(shp->pwdfd) < 0) && errno==EINTR)
+ errno = err;
+ }
+ else
+ {
+ while((chdir(shp->pwd) < 0) && errno==EINTR)
+ errno = err;
+ }
+ }
}
+#endif /* O_SEARCH */
sh_offstate(SH_STOPOK);
if(share&SF_SHARE)
sfset(sfstdin,SF_PUBLIC|SF_SHARE,1);
diff -up ksh-20120801/src/lib/libast/features/common.orig ksh-20120801/src/lib/libast/features/common
--- ksh-20120801/src/lib/libast/features/common.orig 2011-12-12 20:55:33.000000000 +0100
+++ ksh-20120801/src/lib/libast/features/common 2012-10-24 15:54:35.433885131 +0200
@@ -463,6 +463,66 @@ typ uintptr_t stdint.h inttypes.h no{
typedef unsigned _ast_int4_t uintptr_t;
#endif
}end
+typ _Bool = uint8_t
+cat{
+ #if defined(_STDC_C99) || __STDC_VERSION__ >= 199901L
+ #include <stdbool.h>
+ #else
+ #define bool _Bool
+ #define false 0
+ #define true 1
+ #endif
+}end
+tst key __thread -lpthread note{ __thread keyword exists and works with -lpthread }end execute{
+ #include <pthread.h>
+
+ #define INITIAL 1
+ #define LOOP 100
+
+ static __thread int specific = INITIAL;
+ static int global = 0;
+
+ static void* worker(void* arg)
+ {
+ int k;
+ int v;
+ v = (int)(arg - 0);
+ for (k = 0; k < LOOP; ++k)
+ {
+ specific += v;
+ usleep(1);
+ }
+ if (specific != (INITIAL + LOOP * v))
+ global = 1;
+ return 0;
+ }
+ int main()
+ {
+ pthread_t th[2];
+
+ if (pthread_create(&th[0], 0, worker, (void*)0 + 5) ||
+ pthread_create(&th[1], 0, worker, (void*)0 + 7))
+ {
+ NOTE("pthread_create failed");
+ return 1;
+ }
+ pthread_join(th[0], 0);
+ pthread_join(th[1], 0);
+ if (global)
+ {
+ NOTE("__thread variable not thread specific");
+ return 1;
+ }
+ if (specific != INITIAL)
+ {
+ NOTE("main __thread variable changed by another thread");
+ return 1;
+ }
+ return 0;
+ }
+}end no{
+ #define __thread /* __thread keyword does not exist or does not work with -lpthread */
+}end
tst - -DTRY=1 - -DTRY=1 -Dvoid=char - -DTRY=2 - -DTRY=3 - -DTRY=4 output{
#if _STD_ && _hdr_stdarg

@ -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;
}
}

@ -0,0 +1,55 @@
From 035a4cb3f453271b7ae63bcb53a7963b8dbe4c41 Mon Sep 17 00:00:00 2001
From: Anuradha Weeraman <anuradha@weeraman.com>
Date: Thu, 2 Jul 2020 18:29:07 -0400
Subject: [PATCH] Fix segfault if $PATH contains a .paths directory (#55)
ksh crashed if it encountered a .paths directory in any of the
directories in $PATH.
Ref: https://bugs.launchpad.net/ubuntu/+source/ksh/+bug/1534855
src/cmd/ksh93/sh/path.c: path_chkpaths():
- Refuse to read .paths if it's not a regular file
or a symlink to a regular file.
Upstream-commit: 035a4cb3f453271b7ae63bcb53a7963b8dbe4c41
Cherry-picked-by: Lukáš Zaoral <lzaoral@redhat.com>
---
src/cmd/ksh93/sh/path.c | 4 ++++
src/cmd/ksh93/tests/path.sh | 9 +++++++++
2 files changed, 13 insertions(+)
diff --git a/src/cmd/ksh93/sh/path.c b/src/cmd/ksh93/sh/path.c
index 213a2a6c7375..25ade4073dad 100644
--- a/src/cmd/ksh93/sh/path.c
+++ b/src/cmd/ksh93/sh/path.c
@@ -1507,6 +1507,10 @@ static int path_chkpaths(Shell_t *shp,Pathcomp_t *first, Pathcomp_t* old,Pathcom
if((fd=open(stakptr(offset),O_RDONLY))>=0)
{
fstat(fd,&statb);
+ if (!S_ISREG(statb.st_mode)) {
+ close(fd);
+ return 0;
+ }
n = statb.st_size;
stakseek(offset+pp->len+n+2);
sp = stakptr(offset+pp->len);
diff --git a/src/cmd/ksh93/tests/path.sh b/src/cmd/ksh93/tests/path.sh
index c9d8d2485e28..9725c74e31ea 100755
--- a/src/cmd/ksh93/tests/path.sh
+++ b/src/cmd/ksh93/tests/path.sh
@@ -408,5 +408,14 @@ END
END
) || err_exit '${.sh.xxx} variables causes cat not be found'
+# ksh segfaults if $PATH contains a .paths directory
+mkdir -p $tmp/paths-dir-crash/
+cat > $tmp/paths-dir-crash/run.sh <<- EOF
+mkdir -p $tmp/paths-dir-crash/.paths
+export PATH=$tmp/paths-dir-crash:$PATH
+print ok
+EOF
+[[ $($SHELL $tmp/paths-dir-crash/run.sh 2>/dev/null) == ok ]] || err_exit "ksh crashes if PATH contains a .paths directory"
+
exit $((Errors<125?Errors:125))

@ -0,0 +1,13 @@
diff --git a/src/cmd/ksh93/sh/path.c b/src/cmd/ksh93/sh/path.c
index 9965bf5..46e061a 100644
--- a/src/cmd/ksh93/sh/path.c
+++ b/src/cmd/ksh93/sh/path.c
@@ -700,7 +700,7 @@ int path_search(Shell_t *shp,register const char *name,Pathcomp_t **oldpp, int f
{
if(!pp)
pp=sh_isstate(SH_DEFPATH)?shp->defpathlist:shp->pathlist;
- if(pp && strmatch(name,e_alphanum) && (fno=path_opentype(shp,name,pp,1))>=0)
+ if(pp && strlen(name)<256 && strmatch(name,e_alphanum) && (fno=path_opentype(shp,name,pp,1))>=0)
{
if(flag==2)
{

@ -0,0 +1,53 @@
From 9eb8532ccacf1cfdb7ba18f51eba68776852ef7c Mon Sep 17 00:00:00 2001
From: Vincent Mihalkovic <vmihalko@redhat.com>
Date: Thu, 8 Feb 2024 22:10:58 +0100
Subject: [PATCH] Re-fix use of strdup on a NULL pointer (re: 9a9da2c2) (#718)
Thank you @lzaoral for debugging this issue and creating this
reproducer:
$ tty # check that the shell is connected to a pseudoterminal
/dev/pts/4
$ mkdir /var/tmp/chroottest
$ dnf --releasever=39 --installroot=/var/tmp/chroottest install ksh
$ echo "/dev/udp/127.0.0.1/514;0;104" |
sudo tee /var/tmp/chroottest/etc/ksh_audit
$ sudo chroot /var/tmp/chroottest /bin/ksh -lic 'exit 0'
(ksh segfaults)
Analysis: On Linux, ttyname(3)[*] may fail if:
* EBADF Bad file descriptor.
* ENODEV fd refers to a slave pseudoterminal device but the
corresponding pathname could not be found [...].
* ENOTTY fd does not refer to a terminal device.
Calling isatty(3) before ttyname(3) only prevents the first and
third cases.
src/cmd/ksh93/edit/history.c: sh_histinit():
- To catch the second case, let's call ttyname(2) directly, check
for NULL and remove the redundant isatty() call.
[*] https://man7.org/linux/man-pages/man3/ttyname.3.html
---
src/cmd/ksh93/edit/history.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/cmd/ksh93/edit/history.c b/src/cmd/ksh93/edit/history.c
index de5e4a8..222d4bc 100644
--- a/src/cmd/ksh93/edit/history.c
+++ b/src/cmd/ksh93/edit/history.c
@@ -395,7 +395,8 @@ retry:
if(fd>=0)
{
fcntl(fd,F_SETFD,FD_CLOEXEC);
- hp->tty = strdup(ttyname(2));
+ const char* tty = ttyname(2);
+ hp->tty = strdup(tty?tty:"notty");
hp->auditfp = sfnew((Sfio_t*)0,NULL,-1,fd,SF_WRITE);
}
}
--
2.43.0

@ -0,0 +1,57 @@
From 74b4162178c8a2347491b9fd3a22d8e6e1b7e831 Mon Sep 17 00:00:00 2001
From: Johnothan King <johnothanking@protonmail.com>
Date: Wed, 10 Jun 2020 10:19:41 -0700
Subject: [PATCH] Fix `set +r` so that it cannot unset the restricted option
The ksh man page documents that the restricted option cannot be
unset once it is set, which means `set +r` should be invalid.
While this was true for `set +o restricted`, `set +r` was causing
the restricted option to be unset. The fix for this problem comes
from one of Solaris' patches, which adds an error check to prevent
this behavior.
Solaris' patch:
https://github.com/oracle/solaris-userland/blob/master/components/ksh93/patches/020-CR6919590.patch
src/cmd/ksh93/sh/args.c:
- Add an error check to stop `set +r` from unsetting the
restricted option.
src/cmd/ksh93/tests/restricted.sh:
- Add two regression tests to make sure the restricted option
cannot be unset.
(cherry picked from commit bef4fee404d8e24b38fce66420c14a39ac4a123e)
---
src/cmd/ksh93/sh/args.c | 2 ++
src/cmd/ksh93/tests/restricted.sh | 6 ++++++
2 files changed, 8 insertions(+)
diff --git a/src/cmd/ksh93/sh/args.c b/src/cmd/ksh93/sh/args.c
index a4a11012d90a..70bcabea680d 100644
--- a/src/cmd/ksh93/sh/args.c
+++ b/src/cmd/ksh93/sh/args.c
@@ -302,6 +302,8 @@ int sh_argopts(int argc,register char *argv[], void *context)
}
else
{
+ if ((o == SH_RESTRICTED) && sh_isoption(SH_RESTRICTED))
+ errormsg(SH_DICT,ERROR_exit(1),e_restricted,"r"); /* set -r cannot be unset */
if(o==SH_XTRACE)
trace = 0;
off_option(&newflags,o);
diff --git a/src/cmd/ksh93/tests/restricted.sh b/src/cmd/ksh93/tests/restricted.sh
index abf33cc82c04..eb32c01bb62e 100755
--- a/src/cmd/ksh93/tests/restricted.sh
+++ b/src/cmd/ksh93/tests/restricted.sh
@@ -87,4 +87,10 @@ for i in PATH ENV FPATH
do check_restricted "function foo { typeset $i=foobar;};foo" || err_exit "$i can be changed in function by using typeset"
done
+# ======
+# `set +r` and `set +o restricted` should not unset the restricted option
+check_restricted 'set +r' 2> /dev/null || err_exit '`set +r` unsets the restricted option'
+check_restricted 'set +o restricted' 2> /dev/null || err_exit '`set +o restricted` unsets the restricted option'
+
+# ======
exit $((Errors<125?Errors:125))

@ -0,0 +1,79 @@
diff --git a/src/cmd/ksh93/include/io.h b/src/cmd/ksh93/include/io.h
--- a/src/cmd/ksh93/include/io.h
+++ b/src/cmd/ksh93/include/io.h
@@ -79,7 +79,7 @@ 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 bool sh_iovalidfd(Shell_t*, int);
extern int sh_inuse(Shell_t*, int);
extern void sh_iounsave(Shell_t*);
extern void iounpipe(Shell_t*);
diff --git a/src/cmd/ksh93/sh/io.c b/src/cmd/ksh93/sh/io.c
--- a/src/cmd/ksh93/sh/io.c
+++ b/src/cmd/ksh93/sh/io.c
@@ -403,38 +403,50 @@ static short filemapsize;
/* ======== input output and file copying ======== */
-int sh_iovalidfd(Shell_t *shp, int fd)
+bool sh_iovalidfd(Shell_t *shp, int fd)
{
Sfio_t **sftable = shp->sftable;
int max,n, **fdptrs = shp->fdptrs;
unsigned char *fdstatus = shp->fdstatus;
if(fd<0)
- return(0);
+ return(false);
if(fd < shp->gd->lim.open_max)
- return(1);
+ return(true);
max = strtol(astconf("OPEN_MAX",NiL,NiL),NiL,0);
if(fd >= max)
{
errno = EBADF;
- return(0);
+ return(false);
}
n = (fd+16)&~0xf;
- if(n > max)
- n = max;
+ if(n++ > max)
+ n = max+1;
max = shp->gd->lim.open_max;
- shp->sftable = (Sfio_t**)calloc((n+1)*(sizeof(int*)+sizeof(Sfio_t*)+1),1);
- if(max)
- memcpy(shp->sftable,sftable,max*sizeof(Sfio_t*));
+ shp->sftable = (Sfio_t**)calloc((n+1)*(sizeof(int*)+sizeof(Sfio_t*)+sizeof(*fdstatus)),1);
+
+ if(sftable)
+ {
+ --sftable;
+ if(max)
+ memcpy(shp->sftable,sftable,++max*sizeof(Sfio_t*));
+
+ }
+
shp->fdptrs = (int**)(&shp->sftable[n]);
if(max)
- memcpy(shp->fdptrs,fdptrs,max*sizeof(int*));
+ memcpy(shp->fdptrs,--fdptrs,max*sizeof(int*));
shp->fdstatus = (unsigned char*)(&shp->fdptrs[n]);
if(max)
- memcpy(shp->fdstatus,fdstatus,max);
+ memcpy(shp->fdstatus,--fdstatus,max);
+
if(sftable)
free((void*)sftable);
- shp->gd->lim.open_max = n;
- return(1);
+
+ shp->sftable++;
+ shp->fdptrs++;
+ shp->fdstatus++;
+ shp->gd->lim.open_max = n-1;
+ return(true);
}
int sh_inuse(Shell_t *shp, int fd)

@ -0,0 +1,12 @@
diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c
--- a/src/cmd/ksh93/sh/xec.c
+++ b/src/cmd/ksh93/sh/xec.c
@@ -3529,7 +3529,7 @@ int sh_funscope(int argn, char *argv[],int(*fun)(void*),void *arg,int execflg)
}
if(jmpval)
r=shp->exitval;
- if(r>SH_EXITSIG && ((r&SH_EXITMASK)==SIGINT || ((r&SH_EXITMASK)==SIGQUIT)))
+ if(r>SH_EXITSIG && ((r&SH_EXITMASK)==SIGINT || ((r&SH_EXITMASK)==SIGQUIT) || (getenv("_AST_KSH_SIGNAL_BUBBLE"))))
kill(getpid(),r&SH_EXITMASK);
if(jmpval > SH_JMPFUN)
{

@ -0,0 +1,12 @@
diff -up ksh-20120801/src/lib/libast/misc/stk.c.orig ksh-20120801/src/lib/libast/misc/stk.c
--- ksh-20120801/src/lib/libast/misc/stk.c.orig 2022-01-31 16:06:11.923069379 -0300
+++ ksh-20120801/src/lib/libast/misc/stk.c 2022-01-31 16:06:54.896802455 -0300
@@ -76,7 +76,7 @@ struct frame
struct stk
{
_stk_overflow_ stkoverflow; /* called when malloc fails */
- short stkref; /* reference count; */
+ int stkref; /* reference count; */
short stkflags; /* stack attributes */
char *stkbase; /* beginning of current stack frame */
char *stkend; /* end of current stack frame */

@ -0,0 +1,153 @@
From 4604df9ada906e0a6537157a63b6ce7c0509f34d Mon Sep 17 00:00:00 2001
From: Martijn Dekker <martijn@inlv.org>
Date: Thu, 28 Jan 2021 06:08:38 +0000
Subject: [PATCH] Stack robustness fixes from OpenSUSE
Three OpenSUSE patches from:
https://build.opensuse.org/package/show/shells/ksh
As usual, the relevant bug is not currently public:
https://bugzilla.opensuse.org/show_bug.cgi?id=844071
src/cmd/ksh93/sh/xec.c: sh_debug()/sh_exec():
- Fix stk restoration. [bnc#844071]
src/lib/libast/misc/stk.c:
- Fix stk aliasing code. [bnc#844071]
(ksh93-stkalias.dif)
- Make a unknown location fatal in stkset() so that we get a core
dump right away instead of later in an unrelated part of code.
(ksh93-stkset-abort.dif)
src/lib/libast/man/stk.3,
src/lib/libast/man/stak.3:
- Update manual with new stkset() behaviour. (93u+m addition)
(Note that stak is implemented as macros that translate to stk)
---
src/cmd/ksh93/sh/xec.c | 6 +++---
src/lib/libast/man/stak.3 | 5 +++--
src/lib/libast/man/stk.3 | 5 +++--
src/lib/libast/misc/stk.c | 16 ++++++++++------
4 files changed, 19 insertions(+), 13 deletions(-)
diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c
index 23526098ec20..ca3876394d63 100644
--- a/src/cmd/ksh93/sh/xec.c
+++ b/src/cmd/ksh93/sh/xec.c
@@ -646,8 +646,8 @@ int sh_debug(Shell_t *shp, const char *trap, const char *name, const char *subsc
Stk_t *stkp=shp->stk;
struct sh_scoped savst;
Namval_t *np = SH_COMMANDNOD;
- char *sav = stkptr(stkp,0);
int n=4, offset=stktell(stkp);
+ char *sav = stkfreeze(stkp,0);
const char *cp = "+=( ";
Sfio_t *iop = stkstd;
short level;
@@ -702,7 +702,7 @@ int sh_debug(Shell_t *shp, const char *trap, const char *name, const char *subsc
nv_putval(SH_FUNNAMENOD,shp->st.funname,NV_NOFREE);
shp->st = savst;
if(sav != stkptr(stkp,0))
- stkset(stkp,sav,0);
+ stkset(stkp,sav,offset);
else
stkseek(stkp,offset);
return(n);
@@ -962,7 +962,7 @@ int sh_exec(register const Shnode_t *t, int flags)
int ntflag = 0;
#endif
int topfd = shp->topfd;
- char *sav=stkptr(stkp,0);
+ char *sav=stkfreeze(stkp,0);
char *cp=0, **com=0, *comn;
int argn;
int skipexitset = 0;
diff --git a/src/lib/libast/man/stak.3 b/src/lib/libast/man/stak.3
index 5feac69..89e0f54 100644
--- a/src/lib/libast/man/stak.3
+++ b/src/lib/libast/man/stak.3
@@ -109,8 +109,9 @@ the given \fIaddress\fP, and sets the current object to the given
\fIaddress\fP.
The top of the current object is set to \fIoffset\fP bytes from
current object.
-If \fIaddress\fP is not the address of an object on the
-stack the result is undefined.
+If \fIaddress\fP is null, the stack is reset to the beginning.
+If it is non-null, but is not the address of an object on the
+stack, the program aborts and dumps core.
.PP
The remaining functions are used to build the current object incrementally.
An object that is built incrementally on the stack will
diff --git a/src/lib/libast/man/stk.3 b/src/lib/libast/man/stk.3
index 20dfdbefa44c..dd5705cf1188 100644
--- a/src/lib/libast/man/stk.3
+++ b/src/lib/libast/man/stk.3
@@ -110,8 +110,9 @@ the given \fIaddress\fP, and sets the current object to the given
\fIaddress\fP.
The top of the current object is set to \fIoffset\fP bytes from
current object.
-If \fIaddress\fP is not the address of an object on the
-stack the result is undefined.
+If \fIaddress\fP is null, the stack is reset to the beginning.
+If it is non-null, but is not the address of an object on the
+stack, the program aborts and dumps core.
.PP
The \f5sfio\fP(3) output functions can be used to build
current object incrementally.
diff --git a/src/lib/libast/misc/stk.c b/src/lib/libast/misc/stk.c
index 31cd0911dd29..f147ae4fec8c 100644
--- a/src/lib/libast/misc/stk.c
+++ b/src/lib/libast/misc/stk.c
@@ -331,9 +331,9 @@ int stkon(register Sfio_t * stream, register char* loc)
}
/*
* reset the bottom of the current stack back to <loc>
- * if <loc> is not in this stack, then the stack is reset to the beginning
+ * if <loc> is null, then the stack is reset to the beginning
+ * if <loc> is not in this stack, the program dumps core
* otherwise, the top of the stack is set to stkbot+<offset>
- *
*/
char *stkset(register Sfio_t * stream, register char* loc, size_t offset)
{
@@ -377,6 +377,9 @@ char *stkset(register Sfio_t * stream, register char* loc, size_t offset)
break;
frames++;
}
+ /* not found: produce a useful stack trace now instead of a useless one later */
+ if(loc)
+ abort();
/* set stack back to the beginning */
cp = (char*)(fp+1);
if(frames)
@@ -503,7 +506,7 @@ static char *stkgrow(register Sfio_t *stream, size_t size)
register char *cp, *dp=0;
register size_t m = stktell(stream);
size_t endoff;
- char *end=0;
+ char *end=0, *oldbase=0;
int nn=0,add=1;
n += (m + sizeof(struct frame)+1);
if(sp->stkflags&STK_SMALL)
@@ -519,6 +522,7 @@ static char *stkgrow(register Sfio_t *stream, size_t size)
dp=sp->stkbase;
sp->stkbase = ((struct frame*)dp)->prev;
end = fp->end;
+ oldbase = dp;
}
endoff = end - dp;
cp = newof(dp, char, n, nn*sizeof(char*));
@@ -545,10 +549,10 @@ static char *stkgrow(register Sfio_t *stream, size_t size)
if(fp->nalias=nn)
{
fp->aliases = (char**)fp->end;
- if(end && nn>1)
- memmove(fp->aliases,end,(nn-1)*sizeof(char*));
+ if(end && nn>add)
+ memmove(fp->aliases,end,(nn-add)*sizeof(char*));
if(add)
- fp->aliases[nn-1] = dp + roundof(sizeof(struct frame),STK_ALIGN);
+ fp->aliases[nn-1] = oldbase + roundof(sizeof(struct frame),STK_ALIGN);
}
if(m && !dp)
{

@ -0,0 +1,121 @@
From 70f6d758c0f2fda90bc3d49331397ffd62dca3af Mon Sep 17 00:00:00 2001
From: Martijn Dekker <martijn@inlv.org>
Date: Thu, 30 Jul 2020 01:22:11 +0100
Subject: [PATCH] Fix blocked signals after fork(2)ing external command in
subshell
When the classic fork/exec mechanism was used (via sh_fork()) to
run an external command from within a non-forking subshell, SIGINT
was blocked until that subshell was exited. If a subsequent loop
was run in the subshell, it became uninterruptible, e.g.:
$ arch/*/bin/ksh -c '(/usr/bin/true; while :; do :; done); exit'
^C^C^C^C^C
src/cmd/ksh93/sh/xec.c:
- sh_fork() did not reset the savesig variable in the parent part
of the fork when running in a virtual subshell. This had the
effect of delaying signal handling until exiting the subshell.
There is no reason for that subshell check that I can discern, so
this removes it.
I've verified that this causes no regression test failures
even when ksh is compiled with -DSHOPT_SPAWN=0 which means the
classic fork/exec mechanism is always used.
Fixes: https://github.com/ksh93/ksh/issues/86
Cherry-picked-by: Lukáš Zaoral <lzaoral@redhat.com>
Upstream-commit: 70f6d758c0f2fda90bc3d49331397ffd62dca3af
---
src/cmd/ksh93/sh/xec.c | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c
index a6ad50747548..baa8d6d1287a 100644
--- a/src/cmd/ksh93/sh/xec.c
+++ b/src/cmd/ksh93/sh/xec.c
@@ -2951,13 +2951,10 @@ pid_t sh_fork(Shell_t *shp,int flags, int *jobid)
shp->savesig = -1;
while(_sh_fork(shp,parent=fork(),flags,jobid) < 0);
sh_stats(STAT_FORKS);
- if(!shp->subshell)
- {
- sig = shp->savesig;
- shp->savesig = 0;
- if(sig>0)
- kill(getpid(),sig);
- }
+ sig = shp->savesig;
+ shp->savesig = 0;
+ if(sig>0)
+ kill(getpid(),sig);
job_fork(parent);
return(parent);
}
From 91a7c2e3e9feb8ac1391146ebcda9e6adfcd3cfb Mon Sep 17 00:00:00 2001
From: Martijn Dekker <martijn@inlv.org>
Date: Mon, 27 Dec 2021 03:00:15 +0000
Subject: [PATCH] Fix crash/freeze upon interrupting command substitution with
pipe
On some systems (at least Linux and macOS):
1. Run on a command line: t=$(sleep 10|while :; do :; done)
2. Press Ctrl+C in the first 10 seconds.
3. Execute any other command substitution. The shell crashes.
Analysis: Something in the job_wait() call in the sh_subshell()
restore routine may be interrupted by a signal such as SIGINT on
Linux and macOS. Exactly what that interruptible thing is remains
to be determined. In any case, since job_wait() was invoked after
sh_popcontext(), interrupting it caused the sh_subshell() restore
routine to be aborted, resulting in an inconsistent state of the
shell. The fix is to sh_popcontext() at a later stage instead.
src/cmd/ksh93/sh/subshell.c: sh_subshell():
- Move the sh_popcontext() call to near the end, just after
decreasing the subshell level counters and restoring the global
subshell data struct to its parent. This seems like a logical
place for it and could allow other things to be interrupted, too.
- Get rid of the if(shp->subshell) because it is known that the
value is > 0 at this point.
- The short exit routine run if the subshell forked now needs a new
sh_popcontext() call, because this is handled before restoring
the virtual subshell state.
Fixes: https://github.com/ksh93/ksh/issues/397
Cherry-picked-by: Lukáš Zaoral <lzaoral@redhat.com>
Upstream-commit: 91a7c2e3e9feb8ac1391146ebcda9e6adfcd3cfb
---
src/cmd/ksh93/sh/subshell.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/src/cmd/ksh93/sh/subshell.c b/src/cmd/ksh93/sh/subshell.c
@@ -681,10 +681,10 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
sh_trap(trap,0);
free(trap);
}
- sh_popcontext(shp,&buff);
if(shp->subshell==0) /* must be child process */
{
subshell_data = sp->prev;
+ sh_popcontext(shp,&buff);
if(jmpval==SH_JMPSCRIPT)
siglongjmp(*shp->jmplist,jmpval);
shp->exitval &= SH_EXITMASK;
@@ -886,10 +886,10 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_t *t, volatile int flags, int comsub)
#if SHOPT_COSHELL
shp->coshell = sp->coshell;
#endif /* SHOPT_COSHELL */
- if(shp->subshell)
- SH_SUBSHELLNOD->nvalue.s = --shp->subshell;
+ SH_SUBSHELLNOD->nvalue.s = --shp->subshell;
subshell = shp->subshell;
subshell_data = sp->prev;
+ sh_popcontext(shp,&buff);
if(!argsav || argsav->dolrefcnt==argcnt)
sh_argfree(shp,argsav,0);
if(shp->topfd != buff.topfd)

@ -0,0 +1,14 @@
diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c
--- a/src/cmd/ksh93/sh/xec.c
+++ b/src/cmd/ksh93/sh/xec.c
@@ -1647,8 +1647,9 @@ int sh_exec(register const Shnode_t *t, int flags)
{
if (!unpipe)
unpipe = iousepipe(shp);
- sh_subfork();
}
+
+ sh_subfork();
}
}
no_fork = !ntflag && !(type&(FAMP|FPOU)) && !shp->subshell &&

@ -0,0 +1,20 @@
diff --git a/src/cmd/ksh93/sh/path.c b/src/cmd/ksh93/sh/path.c
index d723987..9965bf5 100644
--- a/src/cmd/ksh93/sh/path.c
+++ b/src/cmd/ksh93/sh/path.c
@@ -1791,8 +1791,12 @@ void path_alias(register Namval_t *np,register Pathcomp_t *pp)
{
struct stat statb;
char *sp;
+ Pathcomp_t *old = 0;
nv_offattr(np,NV_NOPRINT);
nv_stack(np,&talias_init);
+ old = (Pathcomp_t*)np->nvalue.cp;
+ if (old && (--old->refcount <= 0))
+ free((void*)old);
np->nvalue.cp = (char*)pp;
pp->refcount++;
nv_setattr(np,NV_TAGGED|NV_NOFREE);
--
2.9.3

@ -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)

@ -0,0 +1,12 @@
diff --git a/src/cmd/ksh93/sh/parse.c b/src/cmd/ksh93/sh/parse.c
--- a/src/cmd/ksh93/sh/parse.c
+++ b/src/cmd/ksh93/sh/parse.c
@@ -742,7 +742,7 @@ static Shnode_t *funct(Lex_t *lexp)
register Shnode_t *t;
register int flag;
struct slnod *volatile slp=0;
- Stak_t *savstak;
+ Stak_t *volatile savstak=0;
Sfoff_t first, last;
struct functnod *volatile fp;
Sfio_t *iop;

@ -0,0 +1,18 @@
diff -up ksh-20120801/src/cmd/ksh93/edit/emacs.c.tabfix ksh-20120801/src/cmd/ksh93/edit/emacs.c
--- ksh-20120801/src/cmd/ksh93/edit/emacs.c.tabfix 2012-07-17 22:44:44.000000000 +0200
+++ ksh-20120801/src/cmd/ksh93/edit/emacs.c 2013-03-07 15:58:59.902161711 +0100
@@ -1011,10 +1011,13 @@ static int escape(register Emacs_t* ep,r
ep->ed->e_tabcount=0;
else
{
+ int oldi = i;
i=ed_getchar(ep->ed,0);
ed_ungetchar(ep->ed,i);
- if(isdigit(i))
+ if(isdigit(i) && oldi=='=')
ed_ungetchar(ep->ed,ESC);
+ else if (isdigit(i) || i=='\t')
+ ep->ed->e_tabcount=0;
}
}
else

@ -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);

@ -0,0 +1,98 @@
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 2015-08-13 15:20:14.022167794 -0300
+++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2015-08-13 15:21:43.263088168 -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.trapcom may change */
+ for (isig = 0; isig < nsig; ++isig)
+ savsig[isig] = shp->st.trapcom[isig] == Empty ? Empty : (shp->st.trapcom[isig] ? strdup(shp->st.trapcom[isig]) : NULL);
/* this nonsense needed for $(trap) */
shp->st.otrapcom = (char**)savsig;
}
@@ -732,7 +735,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] && shp->st.trapcom[isig]!=Empty)
+ free(shp->st.trapcom[isig]);
+ memcpy((char*)&shp->st.trapcom[0],savsig,nsig*sizeof(char*));
free((void*)savsig);
}
shp->options = sp->options;
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 2015-08-13 15:22:09.821062351 -0300
+++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2015-08-13 15:28:06.166662530 -0300
@@ -3383,10 +3383,10 @@ int sh_funscope(int argn, char *argv[],i
struct dolnod *argsav=0,*saveargfor;
struct sh_scoped savst, *prevscope = shp->st.self;
struct argnod *envlist=0;
- int jmpval;
+ int isig,jmpval;
volatile int r = 0;
int n;
- char *savstak;
+ char **savsig;
struct funenv *fp = 0;
struct checkpt *buffp = (struct checkpt*)stkalloc(shp->stk,sizeof(struct checkpt));
Namval_t *nspace = shp->namespace;
@@ -3435,10 +3435,13 @@ int sh_funscope(int argn, char *argv[],i
}
shp->st.cmdname = argv[0];
/* save trap table */
- 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(savstak=stakalloc(nsig),(char*)&shp->st.trapcom[0],nsig);
+ ++nsig;
+ savsig = malloc(nsig * sizeof(char*));
+ /* contents of shp->st.trapcom may change */
+ for (isig = 0; isig < nsig; ++isig)
+ savsig[isig] = shp->st.trapcom[isig] == Empty ? Empty : (shp->st.trapcom[isig] ? strdup(shp->st.trapcom[isig]) : NULL);
}
sh_sigreset(0);
argsav = sh_argnew(shp,argv,&saveargfor);
@@ -3502,10 +3505,14 @@ int sh_funscope(int argn, char *argv[],i
shp->topscope = (Shscope_t*)prevscope;
nv_getval(sh_scoped(shp,IFSNOD));
if(nsig)
- memcpy((char*)&shp->st.trapcom[0],savstak,nsig);
+ {
+ for (isig = 0; isig < nsig; ++isig)
+ if (shp->st.trapcom[isig] && shp->st.trapcom[isig]!=Empty)
+ free(shp->st.trapcom[isig]);
+ memcpy((char*)&shp->st.trapcom[0],savsig,nsig*sizeof(char*));
+ free((void*)savsig);
+ }
shp->trapnote=0;
- if(nsig)
- stakset(savstak,0);
shp->options = options;
shp->last_root = last_root;
if(jmpval == SH_JMPSUB)

@ -0,0 +1,16 @@
diff --git a/src/cmd/ksh93/bltins/typeset.c b/src/cmd/ksh93/bltins/typeset.c
index 15fcd58..8939011 100644
--- a/src/cmd/ksh93/bltins/typeset.c
+++ b/src/cmd/ksh93/bltins/typeset.c
@@ -1442,7 +1442,7 @@ static void print_scan(Sfio_t *file, int flag, Dt_t *root, int option,struct tda
tp->scanmask |= (NV_DOUBLE|NV_EXPNOTE);
if(flag==NV_LTOU || flag==NV_UTOL)
tp->scanmask |= NV_UTOL|NV_LTOU;
- namec = nv_scan(root,nullscan,(void*)tp,tp->scanmask,flag);
+ namec = nv_scan(root,nullscan,(void*)tp,tp->scanmask,flag&~NV_IARRAY);
argv = tp->argnam = (char**)stkalloc(tp->sh->stk,(namec+1)*sizeof(char*));
namec = nv_scan(root, pushname, (void*)tp, tp->scanmask, flag&~NV_IARRAY);
if(mbcoll())
--
2.9.3

@ -0,0 +1,17 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/macro.c.bz1222025 ksh-20120801/src/cmd/ksh93/sh/macro.c
--- ksh-20120801/src/cmd/ksh93/sh/macro.c.bz1222025 2015-09-15 17:28:47.304722569 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/macro.c 2015-09-17 17:49:46.842891942 +0200
@@ -1195,6 +1195,13 @@ retry1:
}
else
v = 0;
+ if(!v && sh_isoption(SH_NOUNSET))
+ {
+ d=fcget();
+ fcseek(-1);
+ if(!(d && strchr(":+-?=",d)))
+ errormsg(SH_DICT,ERROR_exit(1),e_notset,ltos(c));
+ }
break;
case S_ALP:
if(c=='.' && type==0)

@ -0,0 +1,11 @@
diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c
--- a/src/cmd/ksh93/sh/xec.c
+++ b/src/cmd/ksh93/sh/xec.c
@@ -122,6 +122,7 @@ int iousepipe(Shell_t *shp)
return(1);
}
subpipe[2] = sh_fcntl(fd,F_dupfd_cloexec,10);
+ sh_iovalidfd(shp,subpipe[2]);
shp->fdstatus[subpipe[2]] = shp->fdstatus[1];
while(close(fd)<0 && errno==EINTR)
errno = err;

@ -0,0 +1,141 @@
From f9d28935bb93fe7336ba8c5eab4231050de2e11e Mon Sep 17 00:00:00 2001
From: Martijn Dekker <martijn@inlv.org>
Date: Fri, 10 Jul 2020 01:38:13 +0100
Subject: [PATCH] Fix UTF-8 shellquoting for xtrace, printf %q, etc.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This fixes an annoying issue in the shell's quoting algorithm
(used for xtrace (set -x), printf %q, and other things) for UTF-8
locales, that caused it to encode perfectly printable UTF-8
characters unnecessarily and inconsistently. For example:
$ (set -x; : 'aeu aéu')
+ : $'aeu a\u[e9]u'
$ (set -x; : 'aéu aeu')
+ : 'aéu aeu'
$ (set -x; : '正常終了 aeu')
+ : '正常終了 aeu'
$ (set -x; : 'aeu 正常終了')
+ : $'aeu \u[6b63]\u[5e38]\u[7d42]\u[4e86]'
This issue was originally reported by lijo george in May 2017:
https://www.mail-archive.com/ast-developers@lists.research.att.com/msg01958.html
src/cmd/ksh93/sh/string.c:
- Add is_invisible() function that returns true if a character is a
Unicode invisible (non-graph) character, excluding ASCII space.
Ref.: https://unicode.org/charts/PDF/U2000.pdf
- Use a fallback in is_invisible() if we cannot use the system's
iswprint(3); this is the case for the ksh C.UTF-8 locale if the
OS doesn't support that. Fall back to a hardcoded blacklist of
invisible and control characters and put up with not encoding
nonexistent characters into \u[xxxx] escapes.
Ref.: https://unicode.org/charts/PDF/U2000.pdf
- When deciding whether to switch to $'...' quoting mode (state=2),
use is_invisible() instead of testing for ASCII 0-127 range.
- In $'...' quoting mode, use is_invisible() to decide whether to
encode wide characters into \u[xxxx] escapes.
src/cmd/ksh93/tests/builtins.sh:
- Add regression tests for shellquoting Arabic, Japanese and Latin
UTF-8 characters, to be run only in a UTF-8 locale. The Arabic
sample text[*] contains a couple of direction markers that are
expected to be encoded into \u[xxxx] escapes.
[*] source: https://r12a.github.io/scripts/tutorial/summaries/arabic
Upstream-commit: f9d28935bb93fe7336ba8c5eab4231050de2e11e
Cherry-picked-by: Lukáš Zaoral <lzaoral@redhat.com>
---
src/cmd/ksh93/sh/string.c | 32 ++++++++++++++++++++++++++++++--
src/cmd/ksh93/tests/builtins.sh | 18 ++++++++++++++++++
2 files changed, 48 insertions(+), 2 deletions(-)
diff --git a/src/cmd/ksh93/sh/string.c b/src/cmd/ksh93/sh/string.c
index 5eb124b75b23..fd620a09e9b0 100644
--- a/src/cmd/ksh93/sh/string.c
+++ b/src/cmd/ksh93/sh/string.c
@@ -325,6 +325,34 @@ static char *sh_fmtcsv(const char *string)
return(stakptr(offset));
}
+#if SHOPT_MULTIBYTE
+/*
+ * Returns true if c is an invisible Unicode character, excluding ASCII space.
+ * Use iswgraph(3) if possible. In the ksh-specific C.UTF-8 locale, this is
+ * generally not possible as the OS-provided iswgraph(3) doesn't support that
+ * locale. So do a quick test and do our best with a fallback if necessary.
+ */
+static int is_invisible(int c)
+{
+ if(!mbwide()) /* not in multibyte locale? */
+ return(c != ' ' && !isgraph(c)); /* use plain isgraph(3) */
+ else if(iswgraph(0x5E38) && !iswgraph(0xFEFF)) /* can we use iswgraph(3)? */
+ return(c != ' ' && !iswgraph(c)); /* use iswgraph(3) */
+ else /* fallback: */
+ return( c <= 0x001F || /* control characters */
+ c >= 0x007F && c <= 0x009F || /* control characters */
+ c == 0x00A0 || /* non-breaking space */
+ c == 0x061C || /* arabic letter mark */
+ c == 0x1680 || /* ogham space mark */
+ c == 0x180E || /* mongolian vowel separator */
+ c >= 0x2000 && c <= 0x200F || /* spaces and format characters */
+ c >= 0x2028 && c <= 0x202F || /* separators and format characters */
+ c >= 0x205F && c <= 0x206F || /* various format characters */
+ c == 0x3000 || /* ideographic space */
+ c == 0xFEFF ); /* zero-width non-breaking space */
+}
+#endif /* SHOPT_MULTIBYTE */
+
/*
* print <str> quoting chars so that it can be read by the shell
* puts null terminated result on stack, but doesn't freeze it
@@ -363,7 +391,7 @@ char *sh_fmtq(const char *string)
for(;c;c= mbchar(cp))
{
#if SHOPT_MULTIBYTE
- if(c=='\'' || c>=128 || c<0 || !iswprint(c))
+ if(c=='\'' || is_invisible(c))
#else
if(c=='\'' || !isprint(c))
#endif /* SHOPT_MULTIBYTE */
@@ -426,7 +454,7 @@ char *sh_fmtq(const char *string)
cp = op+1;
isbyte = 1;
}
- if(mbwide() && ((cp-op)>1))
+ if(mbwide() && is_invisible(c))
{
sfprintf(staksp,"\\u[%x]",c);
continue;
diff --git a/src/cmd/ksh93/tests/builtins.sh b/src/cmd/ksh93/tests/builtins.sh
index 66d465e0a205..34ef9c914f29 100755
--- a/src/cmd/ksh93/tests/builtins.sh
+++ b/src/cmd/ksh93/tests/builtins.sh
@@ -318,6 +318,24 @@
then err_exit "printf '%..*s' not working"
fi
[[ $(printf '%q\n') == '' ]] || err_exit 'printf "%q" with missing arguments'
+# shell-quoting UTF-8 characters: check for unnecessary encoding
+case ${LC_ALL:-${LC_CTYPE:-${LANG:-}}} in
+( *[Uu][Tt][Ff]8* | *[Uu][Tt][Ff]-8* )
+ expect=$'$\'عندما يريد العالم أن \\u[202a]يتكلّم \\u[202c] ، فهو يتحدّث بلغة يونيكود.\''
+ actual=$(printf %q 'عندما يريد العالم أن ‪يتكلّم ، فهو يتحدّث بلغة يونيكود.')
+ [[ $actual == "$expect" ]] || err_exit 'shell-quoting: Arabic UTF-8 characters' \
+ "(expected $expect; got $actual)"
+ expect="'正常終了 正常終了'"
+ actual=$(printf %q '正常終了 正常終了')
+ [[ $actual == "$expect" ]] || err_exit 'shell-quoting: Japanese UTF-8 characters' \
+ "(expected $expect; got $actual)"
+ expect="'aeu aéu'"
+ actual=$(printf %q 'aeu aéu')
+ [[ $actual == "$expect" ]] || err_exit 'shell-quoting: Latin UTF-8 characters' \
+ "(expected $expect; got $actual)"
+ ;;
+esac
+
# we won't get hit by the one second boundary twice, right?
[[ $(printf '%T\n' now | sed 's/GMT/UTC/') == "$(date)" ]] ||
[[ $(printf '%T\n' now | sed 's/GMT/UTC/') == "$(date)" ]] ||

@ -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)

@ -0,0 +1,21 @@
diff -up ksh-20130214/src/cmd/ksh93/sh/jobs.c.fixkill ksh-20130214/src/cmd/ksh93/sh/jobs.c
--- ksh-20130214/src/cmd/ksh93/sh/jobs.c.fixkill 2012-09-26 17:43:04.000000000 +0200
+++ ksh-20130214/src/cmd/ksh93/sh/jobs.c 2013-02-22 16:38:05.080161740 +0100
@@ -1104,6 +1104,8 @@ static struct process *job_bystring(regi
int job_kill(register struct process *pw,register int sig)
{
+ if(pw==0)
+ goto error;
Shell_t *shp = pw->p_shp;
register pid_t pid;
register int r;
@@ -1127,8 +1129,6 @@ int job_kill(register struct process *pw
#endif /* SIGTSTP */
job_lock();
errno = ECHILD;
- if(pw==0)
- goto error;
pid = pw->p_pid;
#if SHOPT_COSHELL
if(pw->p_cojob)

@ -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);
}

@ -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;

@ -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;

@ -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);
}

@ -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;

@ -0,0 +1,21 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/main.c.orig ksh-20120801/src/cmd/ksh93/sh/main.c
--- ksh-20120801/src/cmd/ksh93/sh/main.c.orig 2015-04-29 16:49:11.502958000 -0300
+++ ksh-20120801/src/cmd/ksh93/sh/main.c 2015-05-08 18:19:55.688776922 -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;
@@ -598,7 +598,7 @@ done:
}
if(jmpval == SH_JMPSCRIPT)
siglongjmp(*shp->jmplist,jmpval);
- else if(jmpval == SH_JMPEXIT)
+ else if(jmpval == SH_JMPEXIT || jmpval == SH_JMPERREXIT)
sh_done(shp,0);
if(fno>0)
sh_close(fno);

@ -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;

@ -0,0 +1 @@
:kshcomp:M::\x0b\x13\x08::/bin/ksh:

@ -0,0 +1,53 @@
#
# /etc/kshrc is sourced in interactive shells. It
# should contain commands to set up aliases, functions,
# options, key bindings, etc.
#
# Set prompts
#PROMPT='[%n@%m]%~%# ' # default prompt
#RPROMPT=' %~' # prompt for right side of screen
_src_etc_profile_d()
{
# from zshrc, with ksh fixes
if [[ ! -o login ]]; then # We're not a login shell
for i in /etc/profile.d/*.sh; do
if [ -r "$i" ]; then
. $i
fi
done
unset i
fi
}
pathmunge () {
case ":${PATH}:" in
*:"$1":*)
;;
*)
if [ "$2" = "after" ]; then
PATH=$PATH:$1
else
PATH=$1:$PATH
fi
esac
}
_src_etc_profile_d
unset -f _src_etc_profile_d
unset -f pathmunge
# key bindings - make Delete, Home, End,... work
keybd_trap () {
case ${.sh.edchar} in
$'\e[1~') .sh.edchar=$'\001';; # Home = beginning-of-line
$'\e[F') .sh.edchar=$'\005';; # End = end-of-line
$'\e[5~') .sh.edchar=$'\e>';; # PgUp = history-previous
$'\e[6~') .sh.edchar=$'\e<';; # PgDn = history-next
$'\e[3~') .sh.edchar=$'\004';; # Delete = delete-char
esac
}
trap keybd_trap KEYBD

@ -0,0 +1,994 @@
%global releasedate 20120801
%global release_date %{lua:reldate=rpm.expand("%{releasedate}");print(("%s-%s-%s"):format(reldate:sub(0,4),reldate:sub(5,6),reldate:sub(7)))}
Name: ksh
Summary: The Original ATT Korn Shell
URL: http://www.kornshell.com/
License: EPL-1.0
Version: %{releasedate}
Release: 267%{?dist}
Source0: http://www.research.att.com/~gsf/download/tgz/ast-ksh.%{release_date}.tgz
Source1: http://www.research.att.com/~gsf/download/tgz/INIT.%{release_date}.tgz
Source2: kshcomp.conf
Source3: kshrc.rhs
Source4: dotkshrc
# expected results of test suite
Source5: expectedresults.log
# don't use not wanted/needed builtins - Fedora/RHEL specific
Patch1: ksh-20070328-builtins.patch
# fix regression test suite to be usable during packagebuild - Fedora/RHEL specific
Patch2: ksh-20100826-fixregr.patch
# fedora/rhel specific, rhbz#619692
Patch6: ksh-20080202-manfix.patch
# rhbz#702008
Patch17: ksh-20100202-pathvar.patch
# rhbz#924440
Patch18: ksh-20100621-fdstatus.patch
# fixes for regressions found in ksh-20120801 rebase
Patch19: ksh-20120801-rmdirfix.patch
Patch20: ksh-20120801-cdfix.patch
Patch21: ksh-20120801-cdfix2.patch
Patch22: ksh-20120801-tabfix.patch
Patch23: ksh-20130214-fixkill.patch
# for ksh <= 2013-05-31, rhbz#960034
Patch24: ksh-20120801-kshmfix.patch
# for ksh <= 2016-06-28, rhbz#921455
Patch25: ksh-20120801-memlik.patch
# for ksh <= 2013-03-20, rhbz#922851
Patch26: ksh-20120801-forkbomb.patch
# for ksh <= 2013-04-19, rhbz#913110
Patch27: ksh-20120801-macro.patch
# not completely upstream yet, rhbz#858263
Patch29: ksh-20130628-longer.patch
# for ksh <= 2013-07-19, rhbz#982142
Patch30: ksh-20120801-mlikfiks.patch
# not yet upstream, related to 2012-08-01 rebase
Patch31: ksh-20120801-covsfix.patch
# rhbz#1007816
Patch32: ksh-20100621-manfix3.patch
# rhbz#1016611
Patch33: ksh-20120801-nomulti.patch
# for ksh <= 2014-01-14, rhbz#
Patch34: ksh-20120801-mtty.patch
# from upstream, rbzh#1048272
Patch35: ksh-20120801-fd2lost.patch
# sent upstream 2014-01, rhbz#1047507
Patch36: ksh-20120801-argvfix.patch
# for ksh <= 2014-01-14, rhbz#1048995
Patch37: ksh-20120801-memlik3.patch
# for ksh <= 2013-04-09, rhbz#960371
Patch38: ksh-20120801-lexfix.patch
# not yet upstream, for ksh <= 2014-02-26, rhbz#1070328
Patch39: ksh-20120801-filecomsubst.patch
# for ksh <= 2014-06-25, rhbz#825520,rhbz#1084406
Patch40: ksh-20120801-crash.patch
# for ksh < 2013-03-19, rhbz#1085385
Patch41: ksh-20120801-sufix.patch
# sent upstream, rhbz#1099935
Patch42: ksh-20140301-fikspand.patch
# for ksh < 2014-04-15, rhbz#1070871
Patch43: ksh-20120801-roundit.patch
# for ksh < 2014-04-15, rhbz#1111120
Patch44: ksh-20120801-heresub.patch
# not included upstream yet, rhbz#1077090
Patch45: ksh-20140415-hokaido.patch
# for ksh < 2012-10-04, rhbz#1121960
Patch46: ksh-20120801-tpstl.patch
# not upstream yet, rhbz#1100215
Patch48: ksh-20120801-fununset.patch
# for ksh < 2014-06-25, rhbz#1109893
Patch49: ksh-20120801-cdfix3.patch
# sent upstream, rhbz#1116506
Patch50: ksh-20120801-locking.patch
# for ksh <= 2013-06-13, rhbz#1133585
Patch51: ksh-20130613-cdfix4.patch
Patch52: ksh-20120801-retfix.patch
# sent upstream, for ksh <= 2014-09-30
Patch53: ksh-20120801-cdfork.patch
# not upstream yet, for ksh <= 2015-04-03, rhbz#1200534
Patch54: ksh-20140801-arraylen.patch
# sent upstream, for ksh <= 2014-09-29, rhbz#1212993
Patch55: ksh-20140801-diskfull.patch
# not upstream yet, rhbz#1192026
Patch56: ksh-20120801-xufix.patch
# sent upstream, for ksh <= 2014-12-18, rhbz#1192119
Patch58: ksh-20120801-alarmifs.patch
# not yet upstream, rhbz#1202439
Patch59: ksh-20140929-safefd.patch
# workaround, for ksh < 2013-05-24, rhbz#1211540
Patch60: ksh-20120801-trapcom.patch
# not yet upstream, rhbz#1217237
Patch64: ksh-20120801-nohupfork.patch
# from upstream, for ksh <= 20130409, rhbz#1241014
Patch65: ksh-20120801-parserfix.patch
# not upstream yet, rhbz#1211538
Patch66: ksh-20120801-oldenvinit.patch
# from upsteam, for ksh < 2012-10-04, rhbz#1193557
Patch67: ksh-20120801-emptyarrayinit.patch
# not upstream yet, rhbz#1371630
Patch68: ksh-20120801-typeset.patch
# not upstream yet, rhbz#1321443
Patch69: ksh-20120801-dotdoublefree.patch
# not upstream yet, rhbz#1405784
Patch70: ksh-20120801-subshell-leak.patch
# rhbz#1189297
Patch71: ksh-20120801-assoc-unset-leak.patch
# rhbz#1222025
Patch72: ksh-20120801-unset-param.patch
# rhbz#1269088
Patch73: ksh-20120801-badgcc.patch
# rhbz#1299484
Patch74: ksh-20120801-mb-after-argvar.patch
Patch75: ksh-20120801-F_dupfd_cloexec.patch
# rhbz#1441142
Patch76: ksh-20120801-kia.patch
# rhbz#1417886
Patch77: ksh-20120801-iso8859.patch
# rhbz#1451057
Patch78: ksh-20120801-syntax-error.patch
# rhbz#1477082
Patch79: ksh-20120801-glibc-build-fix.patch
# rhbz#1459000
Patch80: ksh-20120801-jobwait-sigstop.patch
# rhbz#1462347
Patch81: ksh-20120801-subshell-jobwait.patch
# rhbz#1471874
Patch82: ksh-20120801-posix-exit.patch
# rhbz#1464409
Patch83: ksh-20120801-sh_iovalidfd.patch
# rhbz#1537053
Patch84: ksh-20120801-validate-fd.patch
# There were couple of places where CCFLAGS variable was not passed while
# compiling binaries. This patch fixes it. Loosely related to rhbz#1548549.
Patch85: ksh-20120801-ccflags.patch
Patch86: ksh-20120801-nv_open-memcmp.patch
Patch87: ksh-20120801-covsfix2.patch
# rhbz#1624125
Patch88: ksh-20120801-annocheck.patch
# rhbz#1790547
Patch89: ksh-20120801-cve-2019-14868.patch
# rhbz#1857847
Patch90: ksh-20120801-jobcontrol.patch
# rhbz#2060600
Patch91: ksh-20120801-signal-bubbling.patch
# rhbz#2116372
# upstream commit: https://github.com/ksh93/ksh/commit/4604df9ada906e0a6537157a63b6ce7c0509f34d
Patch92: ksh-20120801-stack-robustness.patch
# rhbz#2116372
# upstream commit: https://github.com/ksh93/ksh/commit/56805b25af24f454cdd477609bcddc984628bc01
Patch93: ksh-20120801-stack-robustness-2.patch
# rhbz#2013909
# upstream commit: https://github.com/ksh93/ksh/commit/6f3b23e6f4d59590a51bfbcc66dc60082728b71d
Patch94: ksh-20120801-segfault-long-command.patch
# rhbz#1948588
# upstream commit: https://github.com/ksh93/ksh/commit/74b4162178c8a2347491b9fd3a22d8e6e1b7e831
Patch95: ksh-20120801-set+r-fix.patch
# RHEL-11982
# upstream commit: https://github.com/ksh93/ksh/commit/9eb8532ccacf1cfdb7ba18f51eba68776852ef7c.patch
Patch96: ksh-20120801-segfault-strdup.patch
# RHEL-12011
# upstream commit: https://github.com/ksh93/ksh/commit/035a4cb3f453271b7ae63bcb53a7963b8dbe4c41
Patch97: ksh-20120801-segfault-cd-paths.patch
# RHEL-5684
# upstream commit: https://github.com/ksh93/ksh/commit/f9d28935bb93fe7336ba8c5eab4231050de2e11e
Patch98: ksh-20120801-xtrace-utf8-quoting.patch
# RHEL-5685
# upstream commit: https://github.com/ksh93/ksh/commit/2075b2b96208ac8b989ca316dcdd674c3f488e2b
Patch99: %{name}-1.0.7-history-trim.patch
# RHEL-11650
# upstream commit: https://github.com/ksh93/ksh/commit/70f6d758c0f2fda90bc3d49331397ffd62dca3af
# upstream commit: https://github.com/ksh93/ksh/commit/91a7c2e3e9feb8ac1391146ebcda9e6adfcd3cfb
Patch100: ksh-20120801-subshell-interrupt-segv.patch
Conflicts: pdksh
Requires: coreutils, diffutils, chkconfig
BuildRequires: bison
# regression test suite uses 'ps' from procps
BuildRequires: procps
Requires(post): grep, coreutils, systemd-units, chkconfig
Requires(postun): sed
Requires(preun): grep, coreutils, chkconfig
Provides: /bin/ksh
%description
KSH-93 is the most recent version of the KornShell by David Korn of
AT&T Bell Laboratories.
KornShell is a shell programming language, which is upward compatible
with "sh" (the Bourne Shell).
%prep
%autosetup -N -c
%autosetup -N -T -D -a 1
%autopatch -p1
#/dev/fd test does not work because of mock
sed -i 's|ls /dev/fd|ls /proc/self/fd|' src/cmd/ksh93/features/options
# sh/main.c was not using CCFLAGS
sed -i '/-c sh\/main.c/s|${mam_cc_FLAGS} |${mam_cc_FLAGS} ${CCFLAGS} |p' src/cmd/ksh93/Mamfile
# disable register for debugging
sed -i 1i"#define register" src/lib/libast/include/ast.h
%build
# rhbz#2226653: -D_std_malloc (disable vmalloc and force use of the operating system's malloc)
XTRAFLAGS=""
for f in -D_std_malloc -Wno-unknown-pragmas -Wno-missing-braces -Wno-unused-result -Wno-return-type -Wno-int-to-pointer-cast -Wno-parentheses -Wno-unused -Wno-unused-but-set-variable -Wno-cpp -P
do
gcc $f -E - </dev/null >/dev/null 2>&1 && XTRAFLAGS="$XTRAFLAGS $f"
done
./bin/package
./bin/package make mamake ||:
./bin/package make mamake ||:
export CCFLAGS="$RPM_OPT_FLAGS $RPM_LD_FLAGS -fno-strict-aliasing $XTRAFLAGS"
export CC=gcc
./bin/package make -S
#cp lib/package/LICENSES/epl LICENSE
%install
mkdir -p %{buildroot}{/bin,%{_bindir},%{_mandir}/man1}
install -p -m 755 arch/*/bin/ksh %{buildroot}%{_bindir}/ksh93
install -p -m 755 arch/*/bin/shcomp %{buildroot}%{_bindir}/shcomp
install -p -m 644 arch/*/man/man1/sh.1 %{buildroot}%{_mandir}/man1/ksh93.1
mkdir -p %{buildroot}%{_sysconfdir}/skel
install -p -m 644 %{SOURCE4} %{buildroot}%{_sysconfdir}/skel/.kshrc
install -p -m 644 %{SOURCE3} %{buildroot}%{_sysconfdir}/kshrc
install -p -D -m 644 %{SOURCE2} %{buildroot}%{_sysconfdir}/binfmt.d/kshcomp.conf
ln -s %{_bindir}/ksh93 %{buildroot}/%{_bindir}/rksh
touch %{buildroot}%{_bindir}/ksh
touch %{buildroot}%{_mandir}/man1/ksh.1.gz
%check
[ -f ./skipcheck -o -f ./../skipcheck ] && exit 0 ||:
%if 0%{?rhel} > 6
%ifarch s390
exit 0
%endif
%endif
export SHELL=$(ls $(pwd)/arch/*/bin/ksh)
cd src/cmd/ksh93/tests/
ulimit -c unlimited
if [ ! -e /dev/fd ]
then
echo "ERROR: /dev/fd does not exist, regression tests skipped"
exit 0
fi
$SHELL ./shtests 2>&1 | tee testresults.log
ls core.* 2>/dev/null ||:
exit 0
sed -e '/begins at/d' -e '/ 0 error/d' -e 's/at [^\[]*\[/\[/' testresults.log -e '/tests skipped/d' >filteredresults.log
if ! cmp filteredresults.log %{SOURCE5} >/dev/null || ls core.*
then
echo "Regression tests failed"
diff -Naurp %{SOURCE5} filteredresults.log
exit -1
fi
%post
for s in /bin/ksh /bin/rksh /usr/bin/ksh /usr/bin/rksh
do
if [ ! -f /etc/shells ]; then
echo "$s" > /etc/shells
else
if ! grep -q '^'"$s"'$' /etc/shells ; then
echo "$s" >> /etc/shells
fi
fi
done
%{_sbindir}/alternatives --install %{_bindir}/ksh ksh \
%{_bindir}/ksh93 50 \
--slave %{_mandir}/man1/ksh.1.gz ksh-man \
%{_mandir}/man1/ksh93.1.gz
#if not symlink we are updating ksh where there was no alternatives before
#so replace with symlink and set alternatives
if [ ! -L %{_bindir}/ksh ]; then
%{_sbindir}/alternatives --auto ksh
ln -sf /etc/alternatives/ksh %{_bindir}/ksh
ln -sf /etc/alternatives/ksh-man %{_mandir}/man1/ksh.1.gz
fi
/bin/systemctl try-restart systemd-binfmt.service >/dev/null 2>&1 || :
%postun
for s in /bin/ksh /bin/rksh /usr/bin/ksh /usr/bin/rksh
do
if [ ! -f $s ]; then
sed -i '\|^'"$s"'$|d' /etc/shells
fi
done
%preun
if [ $1 = 0 ]; then
%{_sbindir}/alternatives --remove ksh %{_bindir}/ksh93
fi
%verifyscript
echo -n "Looking for ksh in /etc/shells... "
if ! grep '^/bin/ksh$' /etc/shells > /dev/null; then
echo "missing"
echo "ksh missing from /etc/shells" >&2
else
echo "found"
fi
%files
%doc src/cmd/ksh93/COMPATIBILITY src/cmd/ksh93/RELEASE src/cmd/ksh93/TYPES
# LICENSE file is missing, temporarily?
%{_bindir}/ksh93
%ghost %{_bindir}/ksh
%{_bindir}/rksh
%{_bindir}/shcomp
%{_mandir}/man1/ksh93.1.gz
%ghost %{_mandir}/man1/ksh.1.gz
%config(noreplace) %{_sysconfdir}/skel/.kshrc
%config(noreplace) %{_sysconfdir}/kshrc
%config(noreplace) %{_sysconfdir}/binfmt.d/kshcomp.conf
%changelog
* Fri Feb 09 2024 Vincent Mihalkovic <vmihalko@redhat.com> - 20120801-267
- Re-fix segfault in strdup
Resolves: RHEL-11982
* Thu Jan 25 2024 Lukáš Zaoral <lzaoral@redhat.com> - 20120801-266
- fix crashes when interrupting subshells (RHEL-11650)
* Wed Jan 03 2024 Vincent Mihalkovic <vmihalko@redhat.com> - 20120801-265
- Fix crash on failure to trim ~/.sh_history (RHEL-5685)
* Wed Nov 22 2023 Vincent Mihalkovic <vmihalko@redhat.com> - 20120801-264
- Remove broken monitor patch
* Thu Nov 09 2023 Lukáš Zaoral <lzaoral@redhat.com> - 20120801-263
- fix UTF-8 quoting in xtrace
Resolves: RHEL-5684
* Wed Nov 08 2023 Lukáš Zaoral <lzaoral@redhat.com> - 20120801-262
- fix segfault in subshell if $PATH contains a .paths directory
Resolves: RHEL-12011
* Tue Oct 31 2023 Lukáš Zaoral <lzaoral@redhat.com> - 20120801-261
- Fix segfault in strdup
Resolves: RHEL-11982
* Mon Sep 18 2023 Lukáš Zaoral <lzaoral@redhat.com> - 20120801-260
- Fix set +r so that it cannot unset the restricted option
Resolves: #1948588
* Fri Aug 25 2023 Vincent Mihalkovic <vmihalko@redhat.com> - 20120801-259
- Fix crash on trying a very long command
Fix license tag
Resolves: #2013909
* Wed Jul 26 2023 Vincent Mihalkovic <vmihalko@redhat.com> - 20120801-258
- disable vmalloc and force use of the operating system's malloc
Resolves: #2226653
* Mon Aug 08 2022 Vincent Mihalkovic <vmihalko@redhat.com> - 20120801-257
- Stack robustness fixes (two patches)
Resolves: #2116372
* Thu Jul 21 2022 Vincent Mihalkovic <vmihalko@redhat.com> - 20120801-256
- Do not evaluate arithmetic expressions from environment variables at startup
Resolves: #2060600
* Mon Jan 03 2022 Vincent Mihalkovic <vmihalko@redhat.com> - 20120801-255
- Fix race conditions running external commands with job control on
Resolves: #1857847
* Thu Feb 06 2020 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-254
- Bump version number to avoid breaking upgrade path
* Wed Jan 08 2020 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-253
- Do not evaluate arithmetic expressions from environment variables at startup
Resolves: #1790547
* Tue Oct 16 2018 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-252
- Use autosetup instead of setup in spec file
* Sun Oct 14 2018 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-251
- Add symlink for rksh
* Sun Oct 14 2018 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-250
- Add alternatives switching with mksh
* Fri Oct 12 2018 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-249
- Fix annocheck failures
Resolves: #1624125
* Mon Aug 13 2018 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-248
- Fix several defects found by coverity
Resolves: #1610785
* Mon Jun 04 2018 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-247
- Fix a crash caused by memcmp()
Resolves: #1583226
* Mon Mar 12 2018 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-246
- Enable standard Fedora LDFLAGS
Resolves: #1548549
* Fri Feb 16 2018 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-245
- Increase release number by 200 to ensure update path
* Mon Feb 12 2018 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-45
- Fix a crash due to out of bounds write
Resolves: #1537053
* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 20120801-44
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
* Tue Nov 21 2017 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-43
- Add virtual provide for /bin/ksh
Resolves: #1513096
* Mon Aug 28 2017 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-42
- Fix a memory corruption
Resolves: #1464409
* Mon Aug 14 2017 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-41
- Use posix exit code if last command exits due to a signal
Resolves: #1471874
* Mon Aug 14 2017 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-40
- Fix condition to fork subshell
Resolves: #1462347
* Mon Aug 14 2017 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-39
- Set terminal foreground process group while resuming process
Resolves: #1459000
* Thu Aug 03 2017 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-38
- Fix build failures caused by update in glibc
Resolves: #1477082
* Thu Aug 03 2017 Fedora Release Engineering <releng@fedoraproject.org> - 20120801-37
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 20120801-36
- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
* Mon May 29 2017 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-35
- Fix memory corruption while parsing functions
Resolves: #1451057
* Tue Apr 25 2017 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-34
- Fix parsing of iso8859 characters
Resolves: #1417886
* Tue Apr 11 2017 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-33
- Avoid spurrious output in kia file creation
Resolves: #1441142
* Fri Mar 10 2017 Michal Hlavinka <mhlavink@redhat.com> - 20120801-32
- add /usr/bin/ksh to /etc/shells (#1381113)
* Fri Mar 03 2017 Michal Hlavinka <mhlavink@redhat.com> - 20120801-31
- use latest set of patches
* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 20120801-30
- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
* Thu Feb 04 2016 Fedora Release Engineering <releng@fedoraproject.org> - 20120801-29
- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
* Thu Aug 27 2015 Michal Hlavinka <mhlavink@redhat.com> - 20120801-28
- fix: in a login shell "( cmd & )" does nothing (#1217238)
* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 20120801-27
- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
* Wed May 06 2015 Michal Hlavinka <mhlavink@redhat.com> - 20120801-26
- do not crash, when disk is full, report an error (#1212994)
* Tue Apr 07 2015 Michal Hlavinka <mhlavink@redhat.com> - 20120801-25
- using trap DEBUG could cause segmentation fault
* Mon Mar 30 2015 Michal Hlavinka <mhlavink@redhat.com> - 20120801-24
- cd builtin could break IO redirection
- fix segfault when handling a trap
- exporting fixed with variable corrupted its data
- and more fixes
* Fri Mar 06 2015 Michal Hlavinka <mhlavink@redhat.com> - 20120801-23
- exporting fixed with variable corrupted its data (#1192027)
* Fri Feb 27 2015 Michal Hlavinka <mhlavink@redhat.com> - 20120801-22
- ksh hangs when command substitution containing a pipe fills out the pipe buffer (#1121204)
* Tue Aug 26 2014 Michal Hlavinka <mhlavink@redhat.com> - 20120801-21
- cd builtin file descriptor operations messed with IO redirections (#1133586)
* Sun Aug 17 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 20120801-20
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
* Tue Jul 22 2014 Michal Hlavinka <mhlavink@redhat.com> - 20120801-19
- fix segfault in job list code
- do not resend signal on termination (#1092132)
- fix brace expansion on/off
- fix incorrect rounding of numsers 0.5 < |x| <1.0 in printf (#1080940)
- fix parser errors related to the end of the here-document marker
- ksh hangs when command substitution fills out the pipe buffer
- using typeset -l with a restricted variabled caused segmentation fault
- monitor mode was documented incorrectly
- do not crash when unsetting running function from another one (#1105139)
- should report an error when trying to cd into directory without execution bit
- job locking mechanism did not survive compiler optimization
- reading a file via command substitution did not work when any of stdin,
stdout or stderr were closed (#1070308)
- fix lexical parser crash
* Tue Jun 10 2014 Michal Hlavinka <mhlavink@redhat.com> - 20120801-18
- fix FTBFS(#1107070)
* Sun Jun 08 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 20120801-17
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
* Tue Feb 11 2014 Michal Hlavinka <mhlavink@redhat.com> - 20120801-16
- ksh could hang when command substitution printed too much data
* Thu Feb 06 2014 Michal Hlavinka <mhlavink@redhat.com> - 20120801-15
- fix lexical parser crash (#960371)
* Fri Jan 17 2014 Michal Hlavinka <mhlavink@redhat.com> - 20120801-14
- fix overflow in subshell loop
* Mon Jan 06 2014 Michal Hlavinka <mhlavink@redhat.com> - 20120801-13
- fix argv rewrite (#1047508)
* Wed Oct 30 2013 Michal Hlavinka <mhlavink@redhat.com> - 20120801-12
- ksh stops on read when monitor mode is enabled
* Sat Aug 03 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 20120801-11
- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
* Wed Jun 12 2013 Michal Hlavinka <mhlavink@redhat.com> - 20120801-10
- fix memory leak
* Mon Jun 10 2013 Michal Hlavinka <mhlavink@redhat.com> - 20120801-9
- monitor mode in scripts wasn't working
* Thu Mar 07 2013 Michal Hlavinka <mhlavink@redhat.com> - 20120801-8
- fix another reproducer for tab completion
* Fri Feb 22 2013 Michal Hlavinka <mhlavink@redhat.com> - 20120801-7
- do not segfault on kill % (#914669)
* Fri Feb 01 2013 Michal Hlavinka <mhlavink@redhat.com> - 20120801-6
- cd file did not produce any error
* Fri Jan 25 2013 Michal Hlavinka <mhlavink@redhat.com> - 20120801-5
- ksh could not enter directories with path containing /.something (#889748)
- file name autocomplete prevented following numeric input (#889745)
* Wed Nov 21 2012 Michal Hlavinka <mhlavink@redhat.com> - 20120801-4
- bind Home, End, Delete,... key correctly for emacs mode
- do not crash when executed from deleted directory
* Fri Sep 14 2012 Michal Hlavinka <mhlavink@redhat.com> - 20120801-3
- fix typo in binfmt config file
- register binary format after package installation
* Thu Sep 13 2012 Michal Hlavinka <mhlavink@redhat.com> - 20120801-2
- add support for direct execution of compiled scripts
* Wed Aug 08 2012 Michal Hlavinka <mhlavink@redhat.com> - 20120801-1
- ksh updated to 20120801
* Tue Jul 31 2012 Michal Hlavinka <mhlavink@redhat.com> - 20120727-1
- ksh updated to 2012-07-27
* Thu Jul 19 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 20120628-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
* Mon Jul 02 2012 Michal Hlavinka <mhlavink@redhat.com> - 20120628-1
- ksh updated to 20120628
* Wed Jun 27 2012 Michal Hlavinka <mhlavink@redhat.com> - 20120626-1
- ksh updated to 20120626
* Fri Jun 22 2012 Michal Hlavinka <mhlavink@redhat.com> - 20120620-1
- ksh updated to 2012-06-20
* Wed Jun 13 2012 Michal Hlavinka <mhlavink@redhat.com> - 20120612-1
- ksh updated to 20120612
* Mon Jun 04 2012 Michal Hlavinka <mhlavink@redhat.com> - 20120531-1
- ksh updated to 2012-05-31
* Mon Mar 19 2012 Michal Hlavinka <mhlavink@redhat.com> - 20120229-2
- do not hang after return code 12
* Wed Mar 14 2012 Michal Hlavinka <mhlavink@redhat.com> - 20120229-1
- ksh updated to 2012-02-29
* Tue Mar 13 2012 Michal Hlavinka <mhlavink@redhat.com> - 20120214-2
- fix tilda expansion in scripts
* Mon Feb 20 2012 Michal Hlavinka <mhlavink@redhat.com> - 20120214-1
- ksh updated to 20120214
* Mon Feb 06 2012 Michal Hlavinka <mhlavink@redhat.com> - 20120202-1
- ksh updated to 20120202
* Thu Jan 05 2012 Michal Hlavinka <mhlavink@redhat.com> - 20120101-1
- ksh updated to 2012-01-01
* Wed Dec 07 2011 Michal Hlavinka <mhlavink@redhat.com> - 20110630-9
- do not crash when browsing through history containing comment (#733813)
* Wed Dec 07 2011 Michal Hlavinka <mhlavink@redhat.com> - 20110630-8
- do not crash when two subseguent dots are used in variable or command name (#733544)
* Mon Dec 05 2011 Michal Hlavinka <mhlavink@redhat.com> - 20110630-7
- fix: ksh can prematurely exit without crash or any error
- make spec work in epel
* Thu Nov 10 2011 Michal Hlavinka <mhlavink@redhat.com> - 20110630-6
- add files to %%doc
* Thu Oct 06 2011 Michal Hlavinka <mhlavink@redhat.com> - 20110630-5
- ksh sometimes returns wrong exit code when pid numbers are being recycled
* Tue Oct 04 2011 Michal Hlavinka <mhlavink@redhat.com> - 20110630-4
- restore tty settings after timed out read (#572291)
* Fri Aug 12 2011 Michal Hlavinka <mhlavink@redhat.com> - 20110630-3
- do not crash when killing last bg job when there is not any
* Wed Aug 03 2011 Michal Hlavinka <mhlavink@redhat.com> - 20110630-2
- fix: IFS manipulation in a function can cause crash
* Fri Jul 01 2011 Michal Hlavinka <mhlavink@redhat.com> - 20110630-1
- ksh updated to 2011-06-30
* Wed Jun 08 2011 Michal Hlavinka <mhlavink@redhat.com> - 20110505-2
- fix: resume of suspended process using pipes does not work (#708909)
* Mon May 09 2011 Michal Hlavinka <mhlavink@redhat.com> - 20110505-1
- ksh updated to 2011-05-05
* Fri Apr 29 2011 Michal Hlavinka <mhlavink@redhat.com> - 20110428-1
- ksh updated to 2011-04-28
* Mon Apr 18 2011 Michal Hlavinka <mhlavink@redhat.com> - 20110415-1
- ksh updated to 2011-04-15
* Tue Mar 29 2011 Michal Hlavinka <mhlavink@redhat.com> - 20110208-3
- fix array definition being treated as fixed array
- fix suspend crashing ksh
* Mon Mar 07 2011 Michal Hlavinka <mhlavink@redhat.com> - 20110208-2
- fix ( ) compound list altering environment
* Wed Feb 09 2011 Michal Hlavinka <mhlavink@redhat.com> - 20110208-1
- ksh updated to 2011-02-08
* Mon Feb 07 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 20110202-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
* Fri Feb 04 2011 Michal Hlavinka <mhlavink@redhat.com> - 20110202-1
- ksh updated to 2011-02-02
* Wed Feb 02 2011 Michal Hlavinka <mhlavink@redhat.com> - 20110131-1
- ksh updated to 2011-01-31
* Fri Jan 28 2011 Michal Hlavinka <mhlavink@redhat.com> - 20110127-1
- ksh updated to 2011-01-27
* Thu Jan 20 2011 Michal Hlavinka <mhlavink@redhat.com> - 20110118-1
- ksh updated to 2011-01-18
* Mon Jan 17 2011 Michal Hlavinka <mhlavink@redhat.com> - 20110104-1
- ksh updated to 2011-01-04
* Thu Dec 23 2010 Michal Hlavinka <mhlavink@redhat.com> - 20101212-2.20101122
- found ugly regression, reverting to 2010-11-22 (with io race patch) for now
* Thu Dec 16 2010 Michal Hlavinka <mhlavink@redhat.com> - 20101212-1
- ksh updated to 2010-12-12
* Mon Dec 06 2010 Michal Hlavinka <mhlavink@redhat.com> - 20101201-2
- fix file io race condition when file was created, but still does not exist
* Fri Dec 03 2010 Michal Hlavinka <mhlavink@redhat.com> - 20101201-1
- ksh updated to 2010-12-01
* Tue Nov 23 2010 Michal Hlavinka <mhlavink@redhat.com> - 20101122-1
- ksh updated to 2010-11-22
* Mon Nov 01 2010 Michal Hlavinka <mhlavink@redhat.com> - 20101026-1
- ksh updated to 2010-10-26
* Tue Oct 12 2010 Michal Hlavinka <mhlavink@redhat.com> - 20101010-1
- ksh updated to 2010-10-10
* Fri Oct 08 2010 Michal Hlavinka <mhlavink@redhat.com> - 20100924-2
- disable only known to be broken builtins, let other enabled
- skip regression tests if /dev/fd is missing
* Tue Sep 28 2010 Michal Hlavinka <mhlavink@redhat.com> - 20100924-1
- ksh updated to 2010-09-24
* Mon Aug 30 2010 Michal Hlavinka <mhlavink@redhat.com> - 20100826-1
- ksh updated to 2010-08-26
- make regression test suite usable during package build
* Fri Aug 13 2010 Michal Hlavinka <mhlavink@redhat.com> - 20100811-1
- ksh updated to 2010-08-11
* Thu Jul 08 2010 Michal Hlavinka <mhlavink@redhat.com> - 20100701-1
- updated to 2010-07-01
* Fri Jun 25 2010 Michal Hlavinka <mhlavink@redhat.com> - 20100621-1
- updated to 2010-06-21
* Tue Jun 15 2010 Michal Hlavinka <mhlavink@redhat.com> - 20100527-2
- add shcomp for shell compiling
* Thu Jun 10 2010 Michal Hlavinka <mhlavink@redhat.com> - 20100527-1
- updated to 2010-05-27
* Mon May 31 2010 Michal Hlavinka <mhlavink@redhat.com> - 20100309-6
- add pathmunge to /etc/kshrc
* Wed May 05 2010 Michal Hlavinka <mhlavink@redhat.com> - 20100309-5
- fix rare cd builtin crash (#578582)
* Wed May 05 2010 Michal Hlavinka <mhlavink@redhat.com> - 20100309-4
- fix infinite loop when whence builtin is used with -q option (#587127)
- fix stdin for double command substitution (#584007)
* Mon Mar 29 2010 Michal Hlavinka <mhlavink@redhat.com> - 20100309-3
- fix typo in last patch
* Fri Mar 26 2010 Michal Hlavinka <mhlavink@redhat.com> - 20100309-2
- restore tty settings after timed out read for utf-8 locale
* Wed Mar 10 2010 Michal Hlavinka <mhlavink@redhat.com> - 20100309-1
- updated to 2010-03-09
- fix mock building - detection of /dev/fd/X
* Mon Jan 04 2010 Michal Hlavinka <mhlavink@redhat.com> - 20100202-1
- updated to 2010-02-02
* Mon Jan 04 2010 Michal Hlavinka <mhlavink@redhat.com> - 20091224-1
- updated to 2009-12-24
* Mon Dec 07 2009 Michal Hlavinka <mhlavink@redhat.com> - 20091206-1
- updated to 2009-12-06
* Fri Dec 04 2009 Michal Hlavinka <mhlavink@redhat.com> - 20091130-1
- updated to 2009-11-30
* Wed Nov 18 2009 Michal Hlavinka <mhlavink@redhat.com> - 20091021-1
- updated to 2009-10-21
* Thu Aug 27 2009 Michal Hlavinka <mhlavink@redhat.com> - 20090630-1
- updated to 2009-06-30
* Fri Jul 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 20090505-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
* Mon May 11 2009 Michal Hlavinka <mhalvink@redhat.com> - 20090505-1
- updated to 2009-05-05
* Tue May 05 2009 Michal Hlavinka <mhalvink@redhat.com> - 20090501-1
- updated to 2009-05-01
* Tue Mar 10 2009 Michal Hlavinka <mhlavink@redhat.com> - 20081104-3
- fix typos in spec file
* Wed Feb 25 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 20081104-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
* Wed Jan 21 2009 Michal Hlavinka <mhlavink@redhat.com> 20081104-1
- update to 2008-11-04
- ast-ksh-locales are not useable remove them
* Tue Oct 21 2008 Michal Hlavinka <mhlavink@redhat.com> 20080725-4
- fix #467025 - Ksh fails to initialise environment when login from graphic console
* Wed Aug 06 2008 Tomas Smetana <tsmetana@redhat.com> 20080725-3
- fix BuildRequires, rebuild
* Tue Aug 5 2008 Tom "spot" Callaway <tcallawa@redhat.com> 20080725-2
- fix license tag
* Mon Jul 28 2008 Tomas Smetana <tsmetana@redhat.com> 20080725-1
- new upstream version
* Thu Jun 26 2008 Tomas Smetana <tsmetana@redhat.com> 20080624-1
- new upstream version
* Mon Feb 11 2008 Tomas Smetana <tsmetana@redhat.com> 20080202-1
- new upstream version
* Wed Jan 30 2008 Tomas Smetana <tsmetana@redhat.com> 20071105-3
- fix #430602 - ksh segfaults after unsetting OPTIND
* Mon Jan 07 2008 Tomas Smetana <tsmetana@redhat.com> 20071105-2
- fix #405381 - ksh will not handle $(xxx) when typeset -r IFS
- fix #386501 - bad group in spec file
* Wed Nov 07 2007 Tomas Smetana <tsmetana@redhat.com> 20071105-1
- new upstream version
* Wed Aug 22 2007 Tomas Smetana <tsmetana@redhat.com> 20070628-1.1
- rebuild
* Thu Jul 12 2007 Tomas Smetana <tsmetana@redhat.com> 20070628-1
- new upstream version
- fix unaligned access messages (Related: #219420)
* Tue May 22 2007 Tomas Smetana <tsmetana@redhat.com> 20070328-2
- fix wrong exit status of spawned process after SIGSTOP
- fix building of debuginfo package, add %%{?dist} to release
- fix handling of SIGTTOU in non-interactive shell
- remove useless builtins
* Thu Apr 19 2007 Tomas Smetana <tsmetana@redhat.com> 20070328-1
- new upstream source
- fix login shell invocation (#182397)
- fix memory leak
* Wed Feb 21 2007 Karsten Hopp <karsten@redhat.com> 20070111-1
- new upstream version
- fix invalid write in uname function
* Wed Jul 12 2006 Jesse Keating <jkeating@redhat.com> - 20060214-1.1
- rebuild
* Thu Jun 01 2006 Karsten Hopp <karsten@redhat.de> 20060214-1
- new upstream source
* Mon Feb 27 2006 Karsten Hopp <karsten@redhat.de> 20060124-3
- PreReq grep, coreutils (#182835)
* Tue Feb 14 2006 Karsten Hopp <karsten@redhat.de> 20060124-2
- make it build in chroots (#180561)
* Mon Feb 13 2006 Karsten Hopp <karsten@redhat.de> 20060124-1
- version 20060124
* Fri Feb 10 2006 Jesse Keating <jkeating@redhat.com> - 20050202-5.1
- bump again for double-long bug on ppc(64)
* Fri Feb 10 2006 Karsten Hopp <karsten@redhat.de> 20050202-5
- rebuild
* Tue Feb 07 2006 Jesse Keating <jkeating@redhat.com> - 20050202-4.1
- rebuilt for new gcc4.1 snapshot and glibc changes
* Thu Feb 02 2006 Karsten Hopp <karsten@redhat.de> 20050202-4
- fix uname -i output
- fix loop (*-path.patch)
- conflict pdksh instead of obsoleting it
* Fri Dec 16 2005 Jesse Keating <jkeating@redhat.com> 20050202-3.1
- rebuilt for new gcj
* Tue May 10 2005 Karsten Hopp <karsten@redhat.de> 20050202-3
- enable debuginfo
* Tue Mar 15 2005 Karsten Hopp <karsten@redhat.de> 20050202-2
- add /usr/bin/ksh link for compatibility with pdksh scripts (#151134)
* Wed Mar 02 2005 Karsten Hopp <karsten@redhat.de> 20050202-1
- update and rebuild with gcc-4
* Tue Mar 01 2005 Karsten Hopp <karsten@redhat.de> 20041225-2
- fix gcc4 build
* Fri Jan 21 2005 Karsten Hopp <karsten@redhat.de> 20041225-1
- rebuild with new ksh tarball (license change)
* Tue Nov 02 2004 Karsten Hopp <karsten@redhat.de> 20040229-11
- disable ia64 for now
* Fri Oct 15 2004 Karsten Hopp <karsten@redhat.de> 20040229-9
- rebuild
* Thu Sep 02 2004 Nalin Dahyabhai <nalin@redhat.com> 20040229-8
- remove '&' from summary
* Thu Sep 02 2004 Bill Nottingham <notting@redhat.com> 20040229-7
- obsolete pdksh (#131303)
* Mon Aug 02 2004 Karsten Hopp <karsten@redhat.de> 20040229-6
- obsolete ksh93, provide ksh93
* Mon Jul 05 2004 Karsten Hopp <karsten@redhat.de> 20040229-3
- add /bin/ksh to /etc/shells
* Wed Jun 16 2004 Karsten Hopp <karsten@redhat.de> 20040229-2
- add ppc64 patch to avoid ppc64 dot symbol problem
* Fri May 28 2004 Karsten Hopp <karsten@redhat.de> 20040229-1
- initial version
Loading…
Cancel
Save