Compare commits

...

No commits in common. "c8" and "c9s" have entirely different histories.
c8 ... c9s

103 changed files with 2140 additions and 3890 deletions

1
.fmf/version Normal file
View File

@ -0,0 +1 @@
1

65
.gitignore vendored
View File

@ -1,2 +1,63 @@
SOURCES/INIT.2012-08-01.tgz
SOURCES/ast-ksh.2012-08-01.tgz
ast-ksh.2010-07-01.tgz
INIT.2010-07-01.tgz
/ast-ksh.2010-08-11.tgz
/INIT.2010-08-11.tgz
/ast-ksh.2010-08-26.tgz
/INIT.2010-08-26.tgz
/ast-ksh.2010-09-24.tgz
/INIT.2010-09-24.tgz
/ast-ksh.2010-10-10.tgz
/INIT.2010-10-10.tgz
/ast-ksh.2010-10-26.tgz
/INIT.2010-10-26.tgz
/ast-ksh.2010-11-22.tgz
/INIT.2010-11-22.tgz
/ast-ksh.2010-12-01.tgz
/INIT.2010-12-01.tgz
/ast-ksh.2010-12-12.tgz
/INIT.2010-12-12.tgz
/ast-ksh.2011-01-04.tgz
/INIT.2011-01-04.tgz
/ast-ksh.2011-01-18.tgz
/INIT.2011-01-18.tgz
/ast-ksh.2011-01-27.tgz
/INIT.2011-01-27.tgz
/ast-ksh.2011-01-31.tgz
/INIT.2011-01-31.tgz
/ast-ksh.2011-02-02.tgz
/INIT.2011-02-02.tgz
/ast-ksh.2011-02-08.tgz
/INIT.2011-02-08.tgz
/ast-ksh.2011-04-15.tgz
/INIT.2011-04-15.tgz
/ast-ksh.2011-04-28.tgz
/INIT.2011-04-28.tgz
/ast-ksh.2011-05-05.tgz
/INIT.2011-05-05.tgz
/ast-ksh.2011-06-30.tgz
/INIT.2011-06-30.tgz
/ast-ksh.2012-01-01.tgz
/INIT.2012-01-01.tgz
/ast-ksh.2012-02-02.tgz
/INIT.2012-02-02.tgz
/ast-ksh.2012-02-14.tgz
/INIT.2012-02-14.tgz
/ast-ksh.2012-02-29.tgz
/INIT.2012-02-29.tgz
/ast-ksh.2012-05-31.tgz
/INIT.2012-05-31.tgz
/ast-ksh.2012-06-12.tgz
/INIT.2012-06-12.tgz
/ast-ksh.2012-06-20.tgz
/INIT.2012-06-20.tgz
/ast-ksh.2012-06-26.tgz
/INIT.2012-06-26.tgz
/ast-ksh.2012-06-28.tgz
/INIT.2012-06-28.tgz
/ast-ksh.2012-07-27.tgz
/INIT.2012-07-27.tgz
/ast-ksh.2012-08-01.tgz
/INIT.2012-08-01.tgz
/ast-ksh.2012-08-01b.tgz
/ksh-1.0.0-beta.1.tar.gz
/ksh-1.0.6.tar.gz

View File

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

View File

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

View File

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

View File

@ -1,54 +0,0 @@
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);

View File

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

View File

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

View File

@ -1,22 +0,0 @@
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);

View File

@ -1,33 +0,0 @@
--- 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)
{

View File

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

View File

@ -1,13 +0,0 @@
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);

View File

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

View File

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

View File

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

View File

@ -1,14 +0,0 @@
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;
}

View File

@ -1,25 +0,0 @@
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);

View File

@ -1,12 +0,0 @@
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);

View File

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

View File

@ -1,58 +0,0 @@
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;
}
}

View File

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

View File

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

View File

@ -1,52 +0,0 @@
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);

View File

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

View File

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

View File

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

View File

@ -1,11 +0,0 @@
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);

View File

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

View File

@ -1,12 +0,0 @@
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;
}
/*

View File

@ -1,38 +0,0 @@
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
/*

View File

@ -1,32 +0,0 @@
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 */

View File

@ -1,74 +0,0 @@
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);

View File

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

View File

@ -1,11 +0,0 @@
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 */

View File

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

View File

@ -1,66 +0,0 @@
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])

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,76 +0,0 @@
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);

View File

@ -1,34 +0,0 @@
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 */

View File

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

View File

@ -1,11 +0,0 @@
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);
}
}

View File

@ -1,11 +0,0 @@
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 */

View File

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

View File

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

View File

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

View File

@ -1,24 +0,0 @@
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);
}

View File

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

View File

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

View File

@ -1,12 +0,0 @@
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;
}
}

View File

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

View File

@ -1,13 +0,0 @@
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)
{

View File

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

View File

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

View File

@ -1,12 +0,0 @@
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)
{

View File

@ -1,12 +0,0 @@
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 */

View File

@ -1,153 +0,0 @@
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)
{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,12 +0,0 @@
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);

View File

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

View File

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

View File

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

View File

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

View File

@ -1,141 +0,0 @@
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)" ]] ||

View File

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

View File

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

View File

@ -1,15 +0,0 @@
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);
}

View File

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

View File

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

View File

@ -1,37 +0,0 @@
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);
}

View File

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

View File

@ -1,21 +0,0 @@
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);

View File

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

1
ci.fmf Normal file
View File

@ -0,0 +1 @@
resultsdb-testcase: separate

6
gating.yaml Normal file
View File

@ -0,0 +1,6 @@
--- !Policy
product_versions:
- rhel-9
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: osci.brew-build./plans/tier1-internal.functional}

194
ksh-1.0.10-blankline.patch Normal file
View File

@ -0,0 +1,194 @@
From a1fcad4bf65fe26a3f9a386b63732ab151ce03ec Mon Sep 17 00:00:00 2001
From: Martijn Dekker <martijn@inlv.org>
Date: Thu, 5 Dec 2024 02:24:39 +0000
Subject: [PATCH] vi: Fix recalling lines starting with whitespace (re:
5eeeed06)
@jghub reports:
> if for some reason a command is entered with leading whitespace,
> the leading whitespace is preserved in the history file (in
> ksh93u+, too). such commands can be recalled from history in 93u+
> without problem, both, in vi and emacs mode.
>
> but in 93u+m such entries are simply ignored when using vi-mode
> (set -o vi), i.e. the k and j commands skip over such entries.
> emacs mode still works just fine.
Analysis: the blankline() function in vi.c and emacs.c is used to
check for whitespace up to the cursor position. This is used for
tab completion and fullscreen editor invocation, where that is
okay, and for history recall, where that should be checking the
entire line instead.
In emacs.c this was not really a problem because arrowing up (or
^P) positions the cursor to the end of the line anyway. But in vi,
arrowing up (or 'k') positions the cursor at the beginning.
src/cmd/ksh93/edit/vi.c:
- Amend blankline() with an 'uptocursor' argument. If nonzero, it
checks the current line for whitespace up to the cursor position,
otherwise it checks the entire line.
- Pass uptocursor==0 to blankline() for history recall and 1 for
tab completion.
src/cmd/ksh93/edit/emacs.c:
- Apply the same change here for consistency, even though it's
perhaps not really necessary. If ever a form of recall is added
that doesn't position the cursor at the end, then that won't
introduce this bug there.
Thanks to @pghvlaans for input into the fix.
Resolves: https://github.com/ksh93/ksh/issues/799
---
src/cmd/ksh93/edit/emacs.c | 14 +++++++-------
src/cmd/ksh93/edit/vi.c | 16 ++++++++--------
src/cmd/ksh93/tests/pty.sh | 12 ++++++++++++
3 files changed, 27 insertions(+), 15 deletions(-)
diff --git a/src/cmd/ksh93/edit/emacs.c b/src/cmd/ksh93/edit/emacs.c
index 128e592..408f6e7 100644
--- a/src/cmd/ksh93/edit/emacs.c
+++ b/src/cmd/ksh93/edit/emacs.c
@@ -178,7 +178,7 @@ static void search(Emacs_t*,genchar*,int);
static void setcursor(Emacs_t*,int, int);
static void show_info(Emacs_t*,const char*);
static void xcommands(Emacs_t*,int);
-static char blankline(Emacs_t*, genchar*);
+static int blankline(Emacs_t*, genchar*, int);
int ed_emacsread(void *context, int fd,char *buff,int scend, int reedit)
{
@@ -720,9 +720,9 @@ update:
cur = eol;
draw(ep,UPDATE);
/* skip blank lines when going up/down in history */
- if(c==cntl('N') && hline != histlines && blankline(ep,out))
+ if(c==cntl('N') && hline != histlines && blankline(ep,out,0))
ed_ungetchar(ep->ed,cntl('N'));
- else if(c==cntl('P') && hline != hismin && blankline(ep,out))
+ else if(c==cntl('P') && hline != hismin && blankline(ep,out,0))
ed_ungetchar(ep->ed,cntl('P'));
continue;
}
@@ -1023,7 +1023,7 @@ static int escape(Emacs_t* ep,genchar *out,int count)
case '*': /* filename expansion */
case '=': /* escape = - list all matching file names */
{
- if(cur<1 || blankline(ep,out))
+ if(cur<1 || blankline(ep,out,1))
{
beep();
return -1;
@@ -1312,7 +1312,7 @@ static void xcommands(Emacs_t *ep,int count)
case cntl('E'): /* invoke emacs on current command */
if(eol>=0 && sh.hist_ptr)
{
- if(blankline(ep,drawbuff))
+ if(blankline(ep,drawbuff,1))
{
cur = 0;
eol = 1;
@@ -1785,11 +1785,11 @@ static int _isword(int c)
/*
* determine if the command line is blank (empty or all whitespace)
*/
-static char blankline(Emacs_t *ep, genchar *out)
+static int blankline(Emacs_t *ep, genchar *out, int uptocursor)
{
int x;
ep->mark = cur;
- for(x=0; x < cur; x++)
+ for(x=0; uptocursor ? (x < cur) : (x <= eol); x++)
{
#if SHOPT_MULTIBYTE
if(!iswspace((wchar_t)out[x]))
diff --git a/src/cmd/ksh93/edit/vi.c b/src/cmd/ksh93/edit/vi.c
index fac40ee..852613c 100644
--- a/src/cmd/ksh93/edit/vi.c
+++ b/src/cmd/ksh93/edit/vi.c
@@ -176,7 +176,7 @@ typedef struct _vi_
static const char paren_chars[] = "([{)]}"; /* for % command */
-static char blankline(Vi_t*);
+static int blankline(Vi_t*, int);
static void cursor(Vi_t*, int);
static void del_line(Vi_t*,int);
static int getcount(Vi_t*,int);
@@ -667,9 +667,9 @@ static int cntlmode(Vi_t *vp)
}
#endif /* SHOPT_EDPREDICT */
/* skip blank lines when going up/down in history */
- if((c=='k' || c=='-') && curhline != histmin && blankline(vp))
+ if((c=='k' || c=='-') && curhline != histmin && blankline(vp,0))
ed_ungetchar(vp->ed,'k');
- else if((c=='j' || c=='+') && curhline != histmax && blankline(vp))
+ else if((c=='j' || c=='+') && curhline != histmax && blankline(vp,0))
ed_ungetchar(vp->ed,'j');
break;
@@ -693,7 +693,7 @@ static int cntlmode(Vi_t *vp)
case 'v':
if(vp->repeat_set==0)
{
- if(blankline(vp) || cur_virt == INVALID)
+ if(blankline(vp,1) || cur_virt == INVALID)
{
cur_virt = 0;
last_virt = cur_virt;
@@ -1294,7 +1294,7 @@ static void getline(Vi_t* vp,int mode)
case '\t': /** command completion **/
{
- if(blankline(vp))
+ if(blankline(vp,1))
{
ed_ringbell();
break;
@@ -2317,7 +2317,7 @@ addin:
case '\\': /** do file name completion in place **/
case '=': /** list file name expansions **/
{
- if(cur_virt == INVALID || blankline(vp))
+ if(cur_virt == INVALID || blankline(vp,1))
return BAD;
/* FALLTHROUGH */
save_v(vp);
@@ -2673,10 +2673,10 @@ yankeol:
/*
* determine if the command line is blank (empty or all whitespace)
*/
-static char blankline(Vi_t *vp)
+static int blankline(Vi_t *vp, int uptocursor)
{
int x;
- for(x=0; x <= cur_virt; x++)
+ for(x=0; x <= (uptocursor ? cur_virt : last_virt); x++)
{
#if SHOPT_MULTIBYTE
if(!iswspace((wchar_t)virtual[x]))
diff --git a/src/cmd/ksh93/tests/pty.sh b/src/cmd/ksh93/tests/pty.sh
index b4f8e28..ea0c616 100755
--- a/src/cmd/ksh93/tests/pty.sh
+++ b/src/cmd/ksh93/tests/pty.sh
@@ -1269,5 +1269,17 @@ w print Exit status $?
u ^Exit status 0\r\n$
!
+((SHOPT_VSH)) && tst $LINENO <<"!"
+L 'k' skips over history entries starting with whitespace
+# https://github.com/ksh93/ksh/issues/799
+
+d 40
+p :test-1:
+w true
+p :test-2:
+c \Ek
+r :test-2: true
+!
+
# ======
exit $((Errors<125?Errors:125))
--
2.49.0

101
ksh-1.0.10-pjob.patch Normal file
View File

@ -0,0 +1,101 @@
From 685f18d36e162c6f6baf44e1c2c8c762ee41466d Mon Sep 17 00:00:00 2001
From: Vincent Mihalkovic <vmihalko@redhat.com>
Date: Sat, 13 Jul 2024 23:45:07 +0200
Subject: [PATCH] jobs: change p_job variable type from short to int (#763)
This change addresses an issue where ksh has undefined behavior
when the number of jobs exceeds `2^15 - 1` (32767), which is the
maximum value for a `short`. The short integer overflow happened in
jobs.c, line 1210.
---
src/cmd/ksh93/include/jobs.h | 5 +++--
src/cmd/ksh93/sh/jobs.c | 11 ++++++-----
2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/src/cmd/ksh93/include/jobs.h b/src/cmd/ksh93/include/jobs.h
index 4ae48d70fb7a..758804118f30 100644
--- a/src/cmd/ksh93/include/jobs.h
+++ b/src/cmd/ksh93/include/jobs.h
@@ -2,7 +2,7 @@
* *
* This software is part of the ast package *
* Copyright (c) 1982-2011 AT&T Intellectual Property *
-* Copyright (c) 2020-2023 Contributors to ksh 93u+m *
+* Copyright (c) 2020-2024 Contributors to ksh 93u+m *
* and is licensed under the *
* Eclipse Public License, Version 2.0 *
* *
@@ -14,6 +14,7 @@
* Martijn Dekker <martijn@inlv.org> *
* Johnothan King <johnothanking@protonmail.com> *
* Anuradha Weeraman <anuradha@debian.org> *
+* Vincent Mihalkovic <vmihalko@redhat.com> *
* *
***********************************************************************/
#ifndef JOB_NFLAG
@@ -51,7 +52,7 @@ struct process
pid_t p_pid; /* process ID */
pid_t p_pgrp; /* process group */
pid_t p_fgrp; /* process group when stopped */
- short p_job; /* job number of process */
+ int p_job; /* job number of 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 */
diff --git a/src/cmd/ksh93/sh/jobs.c b/src/cmd/ksh93/sh/jobs.c
index 871658256f15..86bbe5a9c949 100644
--- a/src/cmd/ksh93/sh/jobs.c
+++ b/src/cmd/ksh93/sh/jobs.c
@@ -13,6 +13,7 @@
* David Korn <dgk@research.att.com> *
* Martijn Dekker <martijn@inlv.org> *
* Johnothan King <johnothanking@protonmail.com> *
+* Vincent Mihalkovic <vmihalko@redhat.com> *
* *
***********************************************************************/
/*
@@ -437,7 +438,7 @@ int job_reap(int sig)
pw->p_flag &= ~P_NOTIFY;
if(job.jobcontrol && pid==pw->p_fgrp && pid==tcgetpgrp(JOBTTY))
{
- px = job_byjid((int)pw->p_job);
+ px = job_byjid(pw->p_job);
for(; px && (px->p_flag&P_DONE); px=px->p_nxtproc);
if(!px)
tcsetpgrp(JOBTTY,job.mypid);
@@ -1528,7 +1529,7 @@ int job_switch(struct process *pw,int bgflag)
{
const char *msg;
job_lock();
- if(!pw || !(pw=job_byjid((int)pw->p_job)))
+ if(!pw || !(pw=job_byjid(pw->p_job)))
{
job_unlock();
return 1;
@@ -1542,7 +1543,7 @@ int job_switch(struct process *pw,int bgflag)
}
if(bgflag=='b')
{
- sfprintf(outfile,"[%d]\t",(int)pw->p_job);
+ sfprintf(outfile,"[%d]\t",pw->p_job);
sh.bckpid = pw->p_pid;
pw->p_flag |= P_BG;
msg = "&";
@@ -1623,7 +1624,7 @@ static struct process *job_unpost(struct process *pwtop,int notify)
sfprintf(sfstderr,"ksh: job line %4d: drop PID=%lld critical=%d PID=%d env=%u\n",__LINE__,(Sflong_t)sh.current_pid,job.in_critical,pwtop->p_pid,pwtop->p_env);
sfsync(sfstderr);
#endif /* DEBUG */
- pwtop = pw = job_byjid((int)pwtop->p_job);
+ pwtop = pw = job_byjid(pwtop->p_job);
if(!pw)
return NULL;
#if SHOPT_BGX
@@ -1664,7 +1665,7 @@ static struct process *job_unpost(struct process *pwtop,int notify)
sfprintf(sfstderr,"ksh: job line %4d: free PID=%lld critical=%d job=%d\n",__LINE__,(Sflong_t)sh.current_pid,job.in_critical,pwtop->p_job);
sfsync(sfstderr);
#endif /* DEBUG */
- job_free((int)pwtop->p_job);
+ job_free(pwtop->p_job);
return NULL;
}

150
ksh-1.0.11-SHLVL.patch Normal file
View File

@ -0,0 +1,150 @@
From d381f5fd4f7fb068315fdf403d30f39452d59699 Mon Sep 17 00:00:00 2001
From: Martijn Dekker <martijn@inlv.org>
Date: Sun, 27 Oct 2024 01:34:38 +0000
Subject: [PATCH] Fix crash on 'exec' after 'unset SHLVL' (re: fa0f9796)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Vincent Mihalkovič (@vmihalko) reports:
> If the user unsets the SHLVL variable and later replaces the
> shell by executing a command, ksh will segfault.
>
> Reproducer
>
> # unset -v SHLVL
> # exec bash
> Segmaentation fault (core dumped)
>
> Reason
>
> The reason for this is that the SHLVL variable is getting
> decremented without any guard making sure it's still in the
> environment, see:
>
> src/cmd/ksh93/bltins/misc.c:
> 145: /* if the main shell is about to be replaced, decrease SHLVL
> to cancel out a subsequent increase */
> 146: if(!sh.realsubshell)
> 147: (*SHLVL->nvalue.ip)--;
This should be fixed so that SHLVL can be unset safely and lose its
special properties like other special variables do.
src/cmd/ksh93/sh/init.c,
src/cmd/ksh93/include/shell.h:
- Move the static 'shlvl' in init.c to the sh state struct, so that
'sh.shlvl' can be accessed from the entire ksh93 code base.
- Change its type from int to int32_t -- this is more correct as
nv_getval() uses this type to retrieve the value. In practice,
this makes no difference because sizeof(int) == sizeof(int32_t),
but this is not guaranteed by the standards.
src/cmd/ksh93/bltins/misc.c:
- Access sh.shlvl directly instead of dereferencing the SHLVL value
pointer, as this pointer is invalidated upon 'unset SHLVL'. This
fixes the bug.
Resolves: https://github.com/ksh93/ksh/issues/788
---
src/cmd/ksh93/bltins/misc.c | 2 +-
src/cmd/ksh93/include/shell.h | 1 +
src/cmd/ksh93/sh/init.c | 15 +++++++--------
src/cmd/ksh93/tests/variables.sh | 7 +++++++
4 files changed, 16 insertions(+), 9 deletions(-)
diff --git a/src/cmd/ksh93/bltins/misc.c b/src/cmd/ksh93/bltins/misc.c
index 92b0183..808241f 100644
--- a/src/cmd/ksh93/bltins/misc.c
+++ b/src/cmd/ksh93/bltins/misc.c
@@ -147,7 +147,7 @@ int b_exec(int argc,char *argv[], Shbltin_t *context)
return 1;
/* if the main shell is about to be replaced, decrease SHLVL to cancel out a subsequent increase */
if(!sh.realsubshell)
- (*SHLVL->nvalue.ip)--;
+ sh.shlvl--;
/* force bad exec to terminate shell */
pp = (struct checkpt*)sh.jmplist;
pp->mode = SH_JMPEXIT;
diff --git a/src/cmd/ksh93/include/shell.h b/src/cmd/ksh93/include/shell.h
index 58e2f2a..0613ceb 100644
--- a/src/cmd/ksh93/include/shell.h
+++ b/src/cmd/ksh93/include/shell.h
@@ -270,6 +270,7 @@ struct Shell_s
* Programs using libshell should not rely on them as they may change. */
int subshell; /* set for virtual subshell */
int realsubshell; /* ${.sh.subshell}, actual subshell level (including virtual and forked) */
+ int32_t shlvl; /* $SHLVL, non-subshell child shell level */
char shcomp; /* set when running shcomp */
unsigned char trapnote; /* set when trap/signal is pending */
struct sh_scoped st; /* scoped information */
diff --git a/src/cmd/ksh93/sh/init.c b/src/cmd/ksh93/sh/init.c
index 15c0736..f4daaac 100644
--- a/src/cmd/ksh93/sh/init.c
+++ b/src/cmd/ksh93/sh/init.c
@@ -224,7 +224,6 @@ static Init_t *nv_init(void);
#if SHOPT_STATS
static void stat_init(void);
#endif
-static int shlvl;
static int rand_shift;
/*
@@ -1354,8 +1353,8 @@ Shell_t *sh_init(int argc,char *argv[], Shinit_f userinit)
sfprintf(sh.strbuf,"%s/.kshrc",nv_getval(HOME));
nv_putval(ENVNOD,sfstruse(sh.strbuf),NV_RDONLY);
}
- *SHLVL->nvalue.ip +=1;
- nv_offattr(SHLVL,NV_IMPORT);
+ sh.shlvl++;
+ nv_offattr(SHLVL,NV_IMPORT);
#if SHOPT_SPAWN
{
/*
@@ -1668,13 +1667,13 @@ int sh_reinit(char *argv[])
memset(sh.st.trapcom,0,(sh.st.trapmax+1)*sizeof(char*));
sh_sigreset(0);
/* increase SHLVL */
- if(!(SHLVL->nvalue.ip))
+ if(!(SHLVL->nvalue.lp))
{
- shlvl = 0;
- SHLVL->nvalue.ip = &shlvl;
+ sh.shlvl = 0;
+ SHLVL->nvalue.lp = &sh.shlvl;
nv_onattr(SHLVL,NV_INTEGER|NV_EXPORT|NV_NOFREE);
}
- *SHLVL->nvalue.ip +=1;
+ sh.shlvl++;
nv_offattr(SHLVL,NV_IMPORT);
sh.st.filename = sh_strdup(sh.lastarg);
nv_delete(NULL, NULL, 0);
@@ -1823,7 +1822,7 @@ static Init_t *nv_init(void)
sh.nvfun.last = (char*)&sh;
sh.nvfun.nofree = 1;
sh.var_base = sh.var_tree = sh_inittree(shtab_variables);
- SHLVL->nvalue.ip = &shlvl;
+ SHLVL->nvalue.lp = &sh.shlvl;
ip->IFS_init.hdr.disc = &IFS_disc;
ip->PATH_init.disc = &RESTRICTED_disc;
ip->PATH_init.nofree = 1;
diff --git a/src/cmd/ksh93/tests/variables.sh b/src/cmd/ksh93/tests/variables.sh
index 7d2de08..08a0789 100755
--- a/src/cmd/ksh93/tests/variables.sh
+++ b/src/cmd/ksh93/tests/variables.sh
@@ -1609,5 +1609,12 @@ got=$(set +x; { "$SHELL" -c '
"(expected status 0, $(printf %q "$exp");" \
"got status $e$( ((e>128)) && print -n /SIG && kill -l "$e"), $(printf %q "$got"))"
+# ======
+# exec after unset SHLVL
+# https://github.com/ksh93/ksh/issues/788
+{ "$SHELL" -c 'unset SHLVL; exec true'; } 2>/dev/null
+(((e=$?)==0)) || err_exit "crash after unsetting SHLVL" \
+ "(expected status 0, got status $e$( ((e>128)) && print -n /SIG && kill -l "$e"))"
+
# ======
exit $((Errors<125?Errors:125))
--
2.47.0

118
ksh-1.0.11-redir.patch Normal file
View File

@ -0,0 +1,118 @@
From 5def43983de3ecfa38c805c02a1f0d6f1581160c Mon Sep 17 00:00:00 2001
From: Martijn Dekker <martijn@inlv.org>
Date: Thu, 31 Oct 2024 20:56:54 +0000
Subject: [PATCH] Add forking workaround for block stdout redir (re: e373e8c1)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reproducer:
ok=$({ true >&2; } >&2; echo OK); echo $ok
This should output "OK" but currently outputs nothing.
Looks like the sh_subfork() workaround must also be implemented for
the TSETIO case in sh_exec(), as that is where redirections for
blocks and compound commands are handled. This avoids inconsistent
behaviour that happens if sh_subfork() is called later for the
inside redirection.
src/cmd/ksh93/sh/xec.c: sh_exec(): case TSETIO:
- Also fork if standard output redirections attached to blocks are
executed within a non-subshare command substitution.
Thanks to Vincent Mihalkovič (@vmihalko) for the report.
Resolves: https://github.com/ksh93/ksh/issues/784
---
NEWS | 8 ++++++++
src/cmd/ksh93/include/version.h | 2 +-
src/cmd/ksh93/sh/xec.c | 15 ++++++++-------
src/cmd/ksh93/tests/io.sh | 32 +++++++++++++++++++++++++++++++-
4 files changed, 48 insertions(+), 9 deletions(-)
diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c
index 01b390d..ca67142 100644
--- a/src/cmd/ksh93/sh/xec.c
+++ b/src/cmd/ksh93/sh/xec.c
@@ -1682,21 +1682,22 @@ int sh_exec(const Shnode_t *t, int flags)
int jmpval, waitall = 0;
int simple = (t->fork.forktre->tre.tretyp&COMMSK)==TCOM;
struct checkpt *buffp = (struct checkpt*)stkalloc(sh.stk,sizeof(struct checkpt));
- if(sh.subshell && !sh.subshare && t->fork.forkio)
+ if(sh.subshell && !sh.subshare)
{
- /* Subshell forking workaround for https://github.com/ksh93/ksh/issues/161
- * Check each redirection for >&- or <&-
+ /* Subshell forking workaround for:
+ * https://github.com/ksh93/ksh/issues/161 (check each redirection for >&- or <&-)
+ * https://github.com/ksh93/ksh/issues/784 (check for stdout in a command substitution)
* TODO: find the elusive real fix */
- struct ionod *i = t->fork.forkio;
- do
+ struct ionod *i;
+ for (i = t->fork.forkio; i; i = i->ionxt)
{
- if((i->iofile & ~(IOUFD|IOPUT)) == (IOMOV|IORAW) && !strcmp(i->ioname,"-"))
- {
+ unsigned f = i->iofile;
+ if ((f & ~(IOUFD|IOPUT))==(IOMOV|IORAW) && !strcmp(i->ioname,"-") || (f & IOUFD)==1 && sh.comsub)
+ {
sh_subfork();
break;
}
}
- while(i = i->ionxt);
}
sh_pushcontext(buffp,SH_JMPIO);
if(type&FPIN)
diff --git a/src/cmd/ksh93/tests/io.sh b/src/cmd/ksh93/tests/io.sh
index 6f70dc1..861bf27 100755
--- a/src/cmd/ksh93/tests/io.sh
+++ b/src/cmd/ksh93/tests/io.sh
@@ -927,7 +927,6 @@ fi
# ======
# Command substitution hangs, writing infinite zero bytes, when redirecting standard output on a built-in that forks
# https://github.com/ksh93/ksh/issues/416
-exp='line'
"$SHELL" -c 'echo "$(ulimit -t unlimited >/dev/null 2>&1; echo "ok $$")"' >out 2>&1 &
pid=$!
(sleep 1; kill -9 "$pid") 2>/dev/null &
@@ -938,6 +937,37 @@ then kill "$!" # the sleep process
else err_exit "comsub hangs after fork with stdout redirection"
fi
+# https://github.com/ksh93/ksh/issues/416#issuecomment-1008866883
+exp='line'
+"$SHELL" -c 'alias foo=bar; echo $(alias foo >/dev/null; echo "$1")' "$0" "$exp" >out 2>&1 &
+pid=$!
+(sleep 1; kill -9 "$pid") 2>/dev/null &
+if wait "$pid" 2>/dev/null
+then kill "$!" # the sleep process
+ [[ $(<out) == "$exp" ]] || err_exit "comsub fails after stdout redirection" \
+ "(expected '$exp', got '$(<out)')"
+else err_exit "comsub hangs after stdout redirection"
+fi
+
+# same bug for compound/block commands: https://github.com/ksh93/ksh/issues/784
+exp=$'funA\nA'
+"$SHELL" -c '
+ BugFunction() {
+ { echo "funA" >&2; } >&2
+ echo A
+ }
+ Result=$(BugFunction)
+ echo $Result
+' >out 2>&1 &
+pid=$!
+(sleep 1; kill -9 "$pid") 2>/dev/null &
+if wait "$pid" 2>/dev/null
+then kill "$!" # the sleep process
+ [[ $(<out) == "$exp" ]] || err_exit "double redirection in command substitution" \
+ "(expected $(printf %q "$exp"), got $(printf %q "$(<out)"))"
+else err_exit "double redirection in command substitution causes shell hang"
+fi
+
# ======
# https://github.com/ksh93/ksh/issues/161
got=$(

View File

@ -0,0 +1,264 @@
From b533bc2feb9a1b58b9cdb3a9f5bc94f4ff060a84 Mon Sep 17 00:00:00 2001
From: Martijn Dekker <martijn@inlv.org>
Date: Fri, 28 Mar 2025 02:59:46 +0000
Subject: [PATCH] Fix segfault upon SIGWINCH after 'stty -echo' (re: 83630f9d)
After disabling terminal echo (stty -echo), ksh either crashes or
writes garbage to the terminal upon resizing the terminal window.
This also affects the use of ksh for 'M-x shell' in emacs.
Analysis: The ed_viread and ed_emacsread functions declare buffers
as local (automatic) variables that are destroyed when the function
exits, but other functions then access then using globally declared
pointers in structs of type Edit_t, Emacs_t and Vi_t.
However, upon 'stty -echo', the terminal cannot be set to raw mode,
so the tty_raw call fails in these two functions. At this point,
they fall back to ed_read and return, never initialising those
pointers. But the SIGWINCH handling routine in edit.c calls redraw
routines that depend on those pointers being valid -- and crash.
src/cmd/ksh93/edit/emacs.c: ed_emacsread():
- Attempt to set raw mode before doing or initialising anything
else: move the tty_raw call and ed_read fallback to the start.
This avoids superfluous init and makes more sense.
- Before returning, reset all global pointers that point to this
function call's local variables to NULL. (To aid with this, use a
'done' goto label and an 'r' variable for the return code.) This
ensures these pointers will be either valid or NULL, making
debugging easier, as well as allowing the code to check for this.
src/cmd/ksh93/edit/vi.c: ed_viread():
- Same changes as for emacs.
src/cmd/ksh93/edit/edit.c: ed_read():
- If e_prompt is NULL, that is now an indication that ed_emacsread
or ed_viread are not being used because the tty_raw call failed;
therefore, skip SIGWINCH handling, except for flushing the notify
buffer (see 667034ff). This fixes the crash.
Thanks to @nickpapadonis for the report.
Resolves: https://github.com/ksh93/ksh/issues/827
---
src/cmd/ksh93/edit/edit.c | 22 ++++++++++++++++++----
src/cmd/ksh93/edit/emacs.c | 27 ++++++++++++++++-----------
src/cmd/ksh93/edit/vi.c | 38 +++++++++++++++-----------------------
3 files changed, 49 insertions(+), 38 deletions(-)
diff --git a/src/cmd/ksh93/edit/edit.c b/src/cmd/ksh93/edit/edit.c
index 1dcef1b..846c0d8 100644
--- a/src/cmd/ksh93/edit/edit.c
+++ b/src/cmd/ksh93/edit/edit.c
@@ -690,6 +690,16 @@ static void ed_nputchar(Edit_t *ep, int n, int c)
}
#endif /* SHOPT_ESH || SHOPT_VSH */
+/*
+ * Show any buffered 'set -b' job notification(s)
+ */
+static void flush_notifybuf(void)
+{
+ char *cp;
+ if(sh.notifybuf && (cp = sfstruse(sh.notifybuf)) && *cp)
+ sfputr(sfstderr, cp, -1);
+}
+
/*
* Do read, restart on interrupt unless SH_SIGSET or SH_SIGTRAP is set
* Use select(2) (via sfpkrd()) to wait for input if possible
@@ -729,7 +739,12 @@ int ed_read(void *context, int fd, char *buff, int size, int reedit)
if(sh.winch && sh_editor_active() && sh_isstate(SH_INTERACTIVE))
{
int n, newsize;
- char *cp;
+ if(!ep->e_prompt)
+ {
+ /* ed_emacsread or ed_viread was unable to put the tty in raw mode */
+ flush_notifybuf();
+ goto skipwinch;
+ }
sh_winsize(NULL,&newsize);
ed_putchar(ep,'\r');
/*
@@ -751,9 +766,7 @@ int ed_read(void *context, int fd, char *buff, int size, int reedit)
ed_putchar(ep,'\r');
}
ed_flush(ep);
- /* show any buffered 'set -b' job notification(s) */
- if(sh.notifybuf && (cp = sfstruse(sh.notifybuf)) && *cp)
- sfputr(sfstderr, cp, -1);
+ flush_notifybuf();
/* update window size */
ep->e_winsz = newsize-1;
if(ep->e_winsz < MINWINDOW)
@@ -777,6 +790,7 @@ int ed_read(void *context, int fd, char *buff, int size, int reedit)
emacs_redraw(ep->e_emacs);
#endif /* SHOPT_ESH && SHOPT_VSH */
}
+ skipwinch:
#endif /* SHOPT_ESH || SHOPT_VSH */
sh.winch = 0;
/* an interrupt that should be ignored */
diff --git a/src/cmd/ksh93/edit/emacs.c b/src/cmd/ksh93/edit/emacs.c
index 1dd6023..128e592 100644
--- a/src/cmd/ksh93/edit/emacs.c
+++ b/src/cmd/ksh93/edit/emacs.c
@@ -185,6 +185,7 @@ int ed_emacsread(void *context, int fd,char *buff,int scend, int reedit)
Edit_t *ed = (Edit_t*)context;
int c;
int i;
+ int r = -1; /* return code */
genchar *out;
int count;
Emacs_t *ep = ed->e_emacs;
@@ -194,6 +195,10 @@ int ed_emacsread(void *context, int fd,char *buff,int scend, int reedit)
genchar *kptr;
char prompt[PRSIZE];
genchar Screen[MAXLINE];
+ /* Set raw mode */
+ if(tty_raw(ERRIO,0) < 0)
+ return reedit ? reedit : ed_read(context, fd, buff, scend, 0);
+ /* Initialize some things */
memset(Screen,0,sizeof(Screen));
if(!ep)
{
@@ -206,10 +211,6 @@ int ed_emacsread(void *context, int fd,char *buff,int scend, int reedit)
ep->screen = Screen;
ep->lastdraw = FINAL;
ep->ehist = 0;
- if(tty_raw(ERRIO,0) < 0)
- {
- return reedit ? reedit : ed_read(context,fd,buff,scend,0);
- }
raw = 1;
/* This mess in case the read system call fails */
ed_setup(ep->ed,fd,reedit);
@@ -240,6 +241,7 @@ int ed_emacsread(void *context, int fd,char *buff,int scend, int reedit)
}
ep->in_mult = hloff; /* save pos in last command */
#endif /* ESH_NFIRST */
+ /* Handle user interrupt, user quit, or EOF */
i = sigsetjmp(env,0);
if (i !=0)
{
@@ -251,10 +253,8 @@ int ed_emacsread(void *context, int fd,char *buff,int scend, int reedit)
}
tty_cooked(ERRIO);
if (i == UEOF)
- {
- return 0; /* EOF */
- }
- return -1; /* some other error */
+ r = 0; /* EOF */
+ goto done;
}
out[reedit] = 0;
if(scend+plen > (MAXLINE-2))
@@ -349,7 +349,8 @@ int ed_emacsread(void *context, int fd,char *buff,int scend, int reedit)
case EOFCHAR:
ed_flush(ep->ed);
tty_cooked(ERRIO);
- return 0;
+ r = 0;
+ goto done;
#ifdef u370
case cntl('S') :
case cntl('Q') :
@@ -754,8 +755,12 @@ process:
#endif /* SHOPT_MULTIBYTE */
i = (int)strlen(buff);
if (i)
- return i;
- return -1;
+ r = i;
+done:
+ /* avoid leaving invalid pointers to destroyed automatic variables */
+ Prompt = NULL;
+ drawbuff = ep->screen = ep->cursor = NULL;
+ return r;
}
static void show_info(Emacs_t *ep,const char *str)
diff --git a/src/cmd/ksh93/edit/vi.c b/src/cmd/ksh93/edit/vi.c
index 0e878df..fac40ee 100644
--- a/src/cmd/ksh93/edit/vi.c
+++ b/src/cmd/ksh93/edit/vi.c
@@ -208,6 +208,7 @@ int ed_viread(void *context, int fd, char *shbuf, int nchar, int reedit)
{
Edit_t *ed = (Edit_t*)context;
int i; /* general variable */
+ int r = -1; /* return value */
int term_char=0; /* read() termination character */
Vi_t *vp = ed->e_vi;
char prompt[PRSIZE+2]; /* prompt */
@@ -218,6 +219,10 @@ int ed_viread(void *context, int fd, char *shbuf, int nchar, int reedit)
int Globals[9]; /* local global variables */
int esc_or_hang=0; /* <ESC> or hangup */
char cntl_char=0; /* TRUE if control character present */
+
+ if( tty_raw(ERRIO,0) < 0 )
+ return reedit ? reedit : ed_read(context, fd, shbuf, nchar, 0);
+
if(!vp)
{
ed->e_vi = vp = sh_newof(0,Vi_t,1,0);
@@ -232,16 +237,9 @@ int ed_viread(void *context, int fd, char *shbuf, int nchar, int reedit)
ed_setup(vp->ed,fd, reedit);
shbuf[reedit] = 0;
- {
- /*** Set raw mode ***/
-
- if(tty_raw(ERRIO,0) < 0 )
- return reedit ? reedit : ed_read(context, fd, shbuf, nchar,0);
- i = last_virt-1;
- }
-
/*** Initialize some things ***/
+ i = last_virt-1;
virtual = (genchar*)shbuf;
#if SHOPT_MULTIBYTE
virtual = (genchar*)roundof((char*)virtual-(char*)0,sizeof(genchar));
@@ -307,18 +305,9 @@ int ed_viread(void *context, int fd, char *shbuf, int nchar, int reedit)
}
virtual[0] = '\0';
tty_cooked(ERRIO);
-
- switch(i)
- {
- case UEOF:
- /*** EOF ***/
- return 0;
-
- case UINTR:
- /** interrupt **/
- return -1;
- }
- return -1;
+ if (i == UEOF)
+ r = 0; /* EOF */
+ goto done;
}
/*** Get a line from the terminal ***/
@@ -363,10 +352,13 @@ int ed_viread(void *context, int fd, char *shbuf, int nchar, int reedit)
if(vp->ed->nhlist)
ed_histlist(vp->ed,0);
#endif /* SHOPT_EDPREDICT */
- return last_virt;
+ r = last_virt;
}
- else
- return -1;
+done:
+ /* avoid leaving invalid pointers to destroyed automatic variables */
+ Prompt = NULL;
+ virtual = physical = window = vp->U_space = vp->u_space = NULL;
+ return r;
}
--
2.49.0

View File

@ -0,0 +1,94 @@
From 96d73c08a2786806f3def1fda66641b81e0af988 Mon Sep 17 00:00:00 2001
From: SHIMIZU Akifumi <shimizu.akifumi@fujitsu.com>
Date: Mon, 7 Apr 2025 19:47:16 +0900
Subject: [PATCH] Fix long multibyte characters paste issue via ssh (#840)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When I paste long multibyte characters(over 80 byte) to ksh via
SSH, the characters are not displayed correctly. For example, the
following input demonstrates the issue. ja_JP.UTF-8 encoding is
used.
Expected command line display:
$ echo "長い文字列を入れるとkshで文字列が乱れる場合があるようです"
Actual command line display:
$ です"echo "長い文字列を入れるとkshで文字列が乱れる場合がある
...with the cursor over the 'e' in 'echo'.
This issue appears to be caused by the ed_read() function splitting
a multibyte character sequence when reading into an 80-byte buffer.
This leads to incorrect character interpretation and display.
Therefore, we edited the code to handle the case where the buffer
size is full in the middle of a multi-byte character.
src/cmd/ksh93/sh/edit.c:
- putstack():
- Before retrying to interpret a multibyte character in case of a
split due to end of buffer, restore the start position 'p'.
- Fix zeroing out errno = EILSEQ.
- ed_getchar(): Avoid a potential buffer overflow in 'readin';
allow for an extra multibyte character, not merely an extra byte.
Co-authored-by: Martijn Dekker <martijn@inlv.org>
---
src/cmd/ksh93/edit/edit.c | 13 ++++++++-----
1 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/src/cmd/ksh93/edit/edit.c b/src/cmd/ksh93/edit/edit.c
index 0ac54ba..1dcef1b 100644
--- a/src/cmd/ksh93/edit/edit.c
+++ b/src/cmd/ksh93/edit/edit.c
@@ -15,6 +15,7 @@
* Johnothan King <johnothanking@protonmail.com> *
* Anuradha Weeraman <anuradha@debian.org> *
* K. Eugene Carlson <kvngncrlsn@gmail.com> *
+* SHIMIZU Akifumi <shimizu.akifumi@fujitsu.com> *
* *
***********************************************************************/
/*
@@ -861,6 +862,7 @@ static int putstack(Edit_t *ep,char string[], int nbyte, int type)
}
else
{
+ char *prevp = p;
again:
if((c=mbchar(p)) >=0)
{
@@ -868,19 +870,20 @@ static int putstack(Edit_t *ep,char string[], int nbyte, int type)
if(type)
c = -c;
}
-#ifdef EILSEQ
- else if(errno == EILSEQ)
- errno = 0;
-#endif
else if((endp-p) < mbmax())
{
+ if(errno == EILSEQ)
+ errno = 0;
if ((c=ed_read(ep,ep->e_fd,endp, 1,0)) == 1)
{
+ p = prevp;
*++endp = 0;
goto again;
}
return c;
}
+ else if(errno == EILSEQ)
+ errno = 0;
else
{
ed_ringbell();
@@ -930,7 +933,7 @@ static int putstack(Edit_t *ep,char string[], int nbyte, int type)
int ed_getchar(Edit_t *ep,int mode)
{
int n, c;
- char readin[LOOKAHEAD+1];
+ char *readin = fmtbuf(LOOKAHEAD + mbmax());
if(!ep->e_lookahead)
{
ed_flush(ep);

View File

@ -0,0 +1,77 @@
From 4350174a5d4acabf78f97b28c6d0ae68ec703e78 Mon Sep 17 00:00:00 2001
From: Martijn Dekker <martijn@inlv.org>
Date: Sun, 30 Mar 2025 00:14:35 +0000
Subject: [PATCH] Fix 'stty -echo' in scripts (re: 41ebb55a)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Vincent Mihalkovič (@vmihalko) reports:
> In ksh versions later than v1.0.0-beta.1, setting stty -echo in a
> script no longer works as expected. This issue did not occur in
> earlier versions.
>
> I performed a git bisect between the last known good tag (reboot)
> and the first known bad tag (v1.0.0-beta.1). The regression was
> introduced in commit 41ebb55a.
>
> Reproducer:
> read a
> stty -echo
> read b
>
> Expected Behavior:
> • Input for a should be visible.
> • Input for b should not be echoed to the terminal.
>
> Actual Behavior:
> • Input for a is visible as expected.
> • Input for b is also visible, despite stty -echo being set.
Analysis:
The problem was that the tty_set(-1, 0, NULL) call below, which
invalidates saved terminal attributes, was no longer being executed
when running a script (note that job.jobcontrol is 0/false for
scripts). See edit.c for the tty_set function and what it does.
src/cmd/ksh93/sh/jobs.c
1423: else if(job.jobcontrol)
1424: {
1425: if(pw->p_pid == tcgetpgrp(JOBTTY))
1426: {
...skipped for brevity...
1430: }
1431: tty_set(-1, 0, NULL);
1432: }
So, after running an external command such as stty, terminal
attributes that should have been invalidated were restored upon the
next 'read'. This was undoing the effect of the stty command.
src/cmd/ksh93/sh/jobs.c: job_wait():
- Move the test for job.jobcontrol so that saved terminal
attributes are again invalidated after running an external
command when job control for interactive shells is not active.
Resolves: https://github.com/ksh93/ksh/issues/836
---
src/cmd/ksh93/sh/jobs.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/cmd/ksh93/sh/jobs.c b/src/cmd/ksh93/sh/jobs.c
index c65bc6e66094..513afb5582ab 100644
--- a/src/cmd/ksh93/sh/jobs.c
+++ b/src/cmd/ksh93/sh/jobs.c
@@ -1420,9 +1420,9 @@ int job_wait(pid_t pid)
kill(sh.current_pid,SIGTSTP);
}
}
- else if(job.jobcontrol)
+ else
{
- if(pw->p_pid == tcgetpgrp(JOBTTY))
+ if(job.jobcontrol && pw->p_pid == tcgetpgrp(JOBTTY))
{
if(pw->p_pgrp==0)
pw->p_pgrp = pw->p_pid;

541
ksh-1.0.6-alarm-1.patch Normal file
View File

@ -0,0 +1,541 @@
diff --git a/src/cmd/ksh93/Mamfile b/src/cmd/ksh93/Mamfile
index f6e6ac8..9d72d87 100644
--- a/src/cmd/ksh93/Mamfile
+++ b/src/cmd/ksh93/Mamfile
@@ -220,30 +220,18 @@ make install
done pmain.o generated
make libshell.a archive
prev shell.req
- make cd_pwd.o
- make bltins/cd_pwd.c
- make include/test.h implicit
- prev include/shtable.h implicit
- make include/defs.h implicit
- prev include/regress.h implicit dontcare
- prev include/shtable.h
- prev include/shell.h
- prev ${PACKAGE_ast_INCLUDE}/endian.h
- prev include/name.h
- prev include/argnod.h implicit
- prev ${PACKAGE_ast_INCLUDE}/cdt.h
- prev ${PACKAGE_ast_INCLUDE}/error.h
- prev ${PACKAGE_ast_INCLUDE}/sfio.h
+ make alarm.o
+ make bltins/alarm.c
+ make FEATURE/time implicit
+ prev features/time
+ exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/time
+ make ${PACKAGE_ast_INCLUDE}/times.h implicit
+ prev ${PACKAGE_ast_INCLUDE}/ast_time.h implicit
prev ${PACKAGE_ast_INCLUDE}/ast.h
- done include/defs.h
- done include/test.h
- make ${PACKAGE_ast_INCLUDE}/ls.h implicit
- prev ${PACKAGE_ast_INCLUDE}/ast_mode.h implicit dontcare
- prev ${PACKAGE_ast_INCLUDE}/ast_fs.h
- prev ${PACKAGE_ast_INCLUDE}/ast_std.h
- done ${PACKAGE_ast_INCLUDE}/ls.h
+ done ${PACKAGE_ast_INCLUDE}/times.h
+ done FEATURE/time generated
make include/builtins.h implicit
- prev include/shtable.h
+ prev include/shtable.h implicit
make FEATURE/dynamic implicit
prev features/dynamic
exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/dynamic
@@ -251,6 +239,36 @@ make install
done FEATURE/dynamic generated
prev ${PACKAGE_ast_INCLUDE}/option.h
done include/builtins.h
+ prev ${PACKAGE_ast_INCLUDE}/error.h
+ make include/defs.h implicit
+ prev include/regress.h implicit
+ prev include/shtable.h
+ prev include/shell.h
+ prev ${PACKAGE_ast_INCLUDE}/endian.h
+ prev include/name.h
+ prev include/argnod.h implicit
+ prev ${PACKAGE_ast_INCLUDE}/cdt.h
+ prev FEATURE/externs
+ prev ${PACKAGE_ast_INCLUDE}/error.h
+ prev ${PACKAGE_ast_INCLUDE}/sfio.h
+ prev ${PACKAGE_ast_INCLUDE}/ast.h
+ done include/defs.h
+ prev shopt.h
+ done bltins/alarm.c
+ exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c bltins/alarm.c
+ done alarm.o generated
+ make cd_pwd.o
+ make bltins/cd_pwd.c
+ make include/test.h implicit
+ prev include/shtable.h
+ prev include/defs.h
+ done include/test.h
+ make ${PACKAGE_ast_INCLUDE}/ls.h implicit
+ prev ${PACKAGE_ast_INCLUDE}/ast_mode.h implicit
+ prev ${PACKAGE_ast_INCLUDE}/ast_fs.h
+ prev ${PACKAGE_ast_INCLUDE}/ast_std.h
+ done ${PACKAGE_ast_INCLUDE}/ls.h
+ prev include/builtins.h
prev include/name.h
make include/path.h implicit
make FEATURE/acct implicit
@@ -341,14 +359,7 @@ make install
make misc.o
make bltins/misc.c
prev ${PACKAGE_ast_INCLUDE}/times.h
- make FEATURE/time implicit
- prev features/time
- exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/time
- make ${PACKAGE_ast_INCLUDE}/times.h implicit
- prev ${PACKAGE_ast_INCLUDE}/ast_time.h implicit dontcare
- prev ${PACKAGE_ast_INCLUDE}/ast.h
- done ${PACKAGE_ast_INCLUDE}/times.h dontcare
- done FEATURE/time generated
+ prev FEATURE/time
prev FEATURE/locale
make include/jobs.h implicit
prev ${PACKAGE_ast_INCLUDE}/vmalloc.h
@@ -1175,7 +1186,7 @@ make install
done edit/hexpand.c
exec - ${CC} ${mam_cc_FLAGS} ${CCFLAGS} -I. -Iinclude -I${PACKAGE_ast_INCLUDE} -D_API_ast=20100309 -DERROR_CONTEXT_T=Error_context_t -c edit/hexpand.c
done hexpand.o generated
- exec - ${AR} rc libshell.a cd_pwd.o cflow.o enum.o getopts.o hist.o misc.o mkservice.o print.o read.o sleep.o trap.o test.o typeset.o ulimit.o umask.o whence.o main.o nvdisc.o nvtype.o arith.o args.o array.o completion.o defs.o edit.o expand.o regress.o fault.o fcin.o
+ exec - ${AR} rc libshell.a alarm.o cd_pwd.o cflow.o enum.o getopts.o hist.o misc.o mkservice.o print.o read.o sleep.o trap.o test.o typeset.o ulimit.o umask.o whence.o main.o nvdisc.o nvtype.o arith.o args.o array.o completion.o defs.o edit.o expand.o regress.o fault.o fcin.o
exec - ${AR} rc libshell.a history.o init.o io.o jobs.o lex.o macro.o name.o nvtree.o parse.o path.o string.o streval.o subshell.o tdump.o timers.o trestore.o waitevent.o xec.o limits.o msg.o strdata.o testops.o keywords.o options.o signals.o aliases.o builtins.o variables.o lexstates.o emacs.o vi.o hexpand.o
exec - (ranlib libshell.a) >/dev/null 2>&1 || true
done libshell.a generated
diff --git a/src/cmd/ksh93/bltins/alarm.c b/src/cmd/ksh93/bltins/alarm.c
new file mode 100644
index 0000000..f31bed7
--- /dev/null
+++ b/src/cmd/ksh93/bltins/alarm.c
@@ -0,0 +1,277 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1982-2012 AT&T Intellectual Property *
+* Copyright (c) 2020-2023 Contributors to ksh 93u+m *
+* and is licensed under the *
+* Eclipse Public License, Version 2.0 *
+* *
+* A copy of the License is available at *
+* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html *
+* (with md5 checksum 84283fa8859daf213bdda5a9f8d1be1d) *
+* *
+* David Korn <dgk@research.att.com> *
+* Martijn Dekker <martijn@inlv.org> *
+* Johnothan King <johnothanking@protonmail.com> *
+* *
+***********************************************************************/
+/*
+ * alarm [-r] [varname [+]when]
+ *
+ * David Korn
+ * AT&T Labs
+ *
+ */
+
+/*
+ * TODO: 2014 email from David Korn cited at <https://bugzilla.redhat.com/1176670>:
+ *
+ * > I never documented the alarm builtin because it is problematic. The
+ * > problem is that traps can't safely be handled asynchronously. What should
+ * > happen is that the trap is marked for execution (sh.trapnote) and run after
+ * > the current command completes. The time trap should wake up the shell if
+ * > it is blocked and it should return and then handle the trap.
+ */
+
+#include "shopt.h"
+#include "defs.h"
+#include <error.h>
+#include "builtins.h"
+#include "FEATURE/time"
+
+#define R_FLAG 1
+#define L_FLAG 2
+
+struct tevent
+{
+ Namfun_t fun;
+ Namval_t *node;
+ Namval_t *action;
+ struct tevent *next;
+ long milli;
+ int flags;
+ void *timeout;
+};
+
+static const char ALARM[] = "alarm";
+
+static void trap_timeout(void*);
+
+/*
+ * insert timeout item on current given list in sorted order
+ */
+static void *time_add(struct tevent *item, void *list)
+{
+ struct tevent *tp = (struct tevent*)list;
+ if(!tp || item->milli < tp->milli)
+ {
+ item->next = tp;
+ list = item;
+ }
+ else
+ {
+ while(tp->next && item->milli > tp->next->milli)
+ tp = tp->next;
+ item->next = tp->next;
+ tp->next = item;
+ }
+ tp = item;
+ tp->timeout = sh_timeradd(tp->milli,tp->flags&R_FLAG,trap_timeout,tp);
+ return list;
+}
+
+/*
+ * delete timeout item from current given list, delete timer
+ */
+static void *time_delete(struct tevent *item, void *list)
+{
+ struct tevent *tp = (struct tevent*)list;
+ if(item==tp)
+ list = tp->next;
+ else
+ {
+ while(tp && tp->next != item)
+ tp = tp->next;
+ if(tp)
+ tp->next = item->next;
+ }
+ if(item->timeout)
+ sh_timerdel(item->timeout);
+ return list;
+}
+
+static void print_alarms(void *list)
+{
+ struct tevent *tp = (struct tevent*)list;
+ while(tp)
+ {
+ if(tp->timeout)
+ {
+ char *name = nv_name(tp->node);
+ if(tp->flags&R_FLAG)
+ {
+ double d = tp->milli;
+ sfprintf(sfstdout,e_alrm1,name,d/1000.);
+ }
+ else
+ sfprintf(sfstdout,e_alrm2,name,nv_getnum(tp->node));
+ }
+ tp = tp->next;
+ }
+}
+
+static void trap_timeout(void* handle)
+{
+ struct tevent *tp = (struct tevent*)handle;
+ sh.trapnote |= SH_SIGALRM;
+ if(!(tp->flags&R_FLAG))
+ tp->timeout = 0;
+ tp->flags |= L_FLAG;
+ sh.sigflag[SIGALRM] |= SH_SIGALRM;
+ if(sh_isstate(SH_TTYWAIT))
+ sh_timetraps();
+}
+
+void sh_timetraps(void)
+{
+ struct tevent *tp, *tpnext;
+ struct tevent *tptop;
+ while(1)
+ {
+ sh.sigflag[SIGALRM] &= ~SH_SIGALRM;
+ tptop= (struct tevent*)sh.st.timetrap;
+ for(tp=tptop;tp;tp=tpnext)
+ {
+ tpnext = tp->next;
+ if(tp->flags&L_FLAG)
+ {
+ tp->flags &= ~L_FLAG;
+ if(tp->action)
+ sh_fun(tp->action,tp->node,NULL);
+ tp->flags &= ~L_FLAG;
+ if(!tp->flags)
+ nv_unset(tp->node);
+ }
+ }
+ if(!(sh.sigflag[SIGALRM]&SH_SIGALRM))
+ break;
+ }
+}
+
+
+/*
+ * This trap function catches "alarm" actions only
+ */
+static char *setdisc(Namval_t *np, const char *event, Namval_t* action, Namfun_t *fp)
+{
+ struct tevent *tp = (struct tevent*)fp;
+ if(!event)
+ return action ? Empty : (char*)ALARM;
+ if(strcmp(event,ALARM)!=0)
+ {
+ /* try the next level */
+ return nv_setdisc(np, event, action, fp);
+ }
+ if(action==np)
+ action = tp->action;
+ else
+ tp->action = action;
+ return action ? (char*)action : Empty;
+}
+
+/*
+ * catch assignments and set alarm traps
+ */
+static void putval(Namval_t* np, const char* val, int flag, Namfun_t* fp)
+{
+ struct tevent *tp = (struct tevent*)fp;
+ double d;
+ if(val)
+ {
+ double now;
+#ifdef timeofday
+ struct timeval tmp;
+ timeofday(&tmp);
+ now = tmp.tv_sec + 1.e-6*tmp.tv_usec;
+#else
+ now = (double)time(NULL);
+#endif /* timeofday */
+ nv_putv(np,val,flag,fp);
+ d = nv_getnum(np);
+ if(*val=='+')
+ {
+ double x = d + now;
+ nv_putv(np,(char*)&x,NV_INTEGER|NV_DOUBLE,fp);
+ }
+ else
+ d -= now;
+ tp->milli = 1000*(d+.0005);
+ if(tp->timeout)
+ sh.st.timetrap = time_delete(tp,sh.st.timetrap);
+ if(tp->milli > 0)
+ sh.st.timetrap = time_add(tp,sh.st.timetrap);
+ }
+ else
+ {
+ tp = (struct tevent*)nv_stack(np, NULL);
+ sh.st.timetrap = time_delete(tp,sh.st.timetrap);
+ nv_unset(np);
+ free(fp);
+ }
+}
+
+static const Namdisc_t alarmdisc =
+{
+ sizeof(struct tevent),
+ putval,
+ 0,
+ 0,
+ setdisc,
+};
+
+int b_alarm(int argc,char *argv[],Shbltin_t *context)
+{
+ int n,rflag=0;
+ Namval_t *np;
+ struct tevent *tp;
+ while (n = optget(argv, sh_optalarm)) switch (n)
+ {
+ case 'r':
+ rflag = R_FLAG;
+ break;
+ case ':':
+ errormsg(SH_DICT,2, "%s", opt_info.arg);
+ break;
+ case '?':
+ errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
+ UNREACHABLE();
+ }
+ argc -= opt_info.index;
+ argv += opt_info.index;
+ if(error_info.errors)
+ {
+ errormsg(SH_DICT,ERROR_usage(2),optusage(NULL));
+ UNREACHABLE();
+ }
+ if(argc==0)
+ {
+ print_alarms(sh.st.timetrap);
+ return 0;
+ }
+ if(argc!=2)
+ {
+ errormsg(SH_DICT,ERROR_usage(2),optusage(NULL));
+ UNREACHABLE();
+ }
+ np = nv_open(argv[0],sh.var_tree,NV_NOARRAY|NV_VARNAME);
+ if(!nv_isnull(np))
+ nv_unset(np);
+ nv_setattr(np, NV_DOUBLE);
+ tp = sh_newof(NULL,struct tevent,1,0);
+ tp->fun.disc = &alarmdisc;
+ tp->flags = rflag;
+ tp->node = np;
+ nv_stack(np,(Namfun_t*)tp);
+ nv_putval(np, argv[1], 0);
+ return 0;
+}
diff --git a/src/cmd/ksh93/bltins/sleep.c b/src/cmd/ksh93/bltins/sleep.c
index b34e62d..3bb55b1 100644
--- a/src/cmd/ksh93/bltins/sleep.c
+++ b/src/cmd/ksh93/bltins/sleep.c
@@ -127,6 +127,8 @@ skip:
if(tloc < (now=time(NULL)))
break;
d = (double)(tloc-now);
+ if(sh.sigflag[SIGALRM]&SH_SIGTRAP)
+ sh_timetraps();
}
return 0;
}
diff --git a/src/cmd/ksh93/data/builtins.c b/src/cmd/ksh93/data/builtins.c
index 760b7ce..22ea156 100644
--- a/src/cmd/ksh93/data/builtins.c
+++ b/src/cmd/ksh93/data/builtins.c
@@ -116,6 +116,7 @@ const struct shtable3 shtab_builtins[] =
"pwd", NV_BLTIN|BLT_ENV, bltin(pwd),
"read", NV_BLTIN|BLT_ENV, bltin(read),
"sleep", NV_BLTIN, bltin(sleep),
+ "alarm", NV_BLTIN|BLT_ENV, bltin(alarm),
"times", NV_BLTIN|BLT_ENV|BLT_SPC, bltin(times),
"ulimit", NV_BLTIN|BLT_ENV, bltin(ulimit),
"umask", NV_BLTIN|BLT_ENV, bltin(umask),
@@ -2170,6 +2171,8 @@ const char sh_optwhence[] =
;
+const char e_alrm1[] = "alarm -r %s +%.3g\n";
+const char e_alrm2[] = "alarm %s %.3f\n";
const char e_baddisc[] = "%s: invalid discipline function";
const char e_nofork[] = "cannot fork";
const char e_nosignal[] = "%s: unknown signal name";
diff --git a/src/cmd/ksh93/include/builtins.h b/src/cmd/ksh93/include/builtins.h
index 34c697c..f6b3f59 100644
--- a/src/cmd/ksh93/include/builtins.h
+++ b/src/cmd/ksh93/include/builtins.h
@@ -115,6 +115,8 @@ extern int b_times(int, char*[],Shbltin_t*);
extern short b_enum_nelem(Namfun_t*);
+extern const char e_alrm1[];
+extern const char e_alrm2[];
extern const char e_badfun[];
extern const char e_baddisc[];
extern const char e_nofork[];
diff --git a/src/cmd/ksh93/include/defs.h b/src/cmd/ksh93/include/defs.h
index 306ea7e..b5bfb67 100644
--- a/src/cmd/ksh93/include/defs.h
+++ b/src/cmd/ksh93/include/defs.h
@@ -143,6 +143,7 @@ extern void sh_subjobcheck(pid_t);
extern int sh_subsavefd(int);
extern void sh_subtmpfile(void);
extern char *sh_substitute(const char*,const char*,char*);
+extern void sh_timetraps(void);
extern const char *_sh_translate(const char*);
extern int sh_trace(char*[],int);
extern void sh_trim(char*);
diff --git a/src/cmd/ksh93/include/fault.h b/src/cmd/ksh93/include/fault.h
index b57a0ab..7750f80 100644
--- a/src/cmd/ksh93/include/fault.h
+++ b/src/cmd/ksh93/include/fault.h
@@ -58,6 +58,7 @@ typedef void (*SH_SIGTYPE)(int,void(*)(int));
#define SH_SIGIGNORE 040 /* default is ignore signal */
#define SH_SIGINTERACTIVE 0100 /* handle interactive specially */
#define SH_SIGTSTP 0200 /* tstp signal received */
+#define SH_SIGALRM 0200 /* timer alarm received */
#define SH_SIGTERM SH_SIGOFF /* term signal received */
#define SH_SIGRUNTIME 0400 /* runtime value */
diff --git a/src/cmd/ksh93/include/shell.h b/src/cmd/ksh93/include/shell.h
index 57c402d..9794995 100644
--- a/src/cmd/ksh93/include/shell.h
+++ b/src/cmd/ksh93/include/shell.h
@@ -211,6 +211,7 @@ struct sh_scoped
char **otrap; /* save parent pseudosignals for v=$(trap) */
char **trapcom; /* EXIT and signals */
char **otrapcom; /* save parent EXIT and signals for v=$(trap) */
+ void *timetrap;
struct Ufunction *real_fun; /* current 'function name' function */
int repl_index;
char *repl_arg;
diff --git a/src/cmd/ksh93/sh/fault.c b/src/cmd/ksh93/sh/fault.c
index 3409a6c..510bf56 100644
--- a/src/cmd/ksh93/sh/fault.c
+++ b/src/cmd/ksh93/sh/fault.c
@@ -447,6 +447,8 @@ void sh_chktrap(void)
sh_exit(sh.exitval);
}
}
+ if(sh.sigflag[SIGALRM]&SH_SIGALRM)
+ sh_timetraps();
#if SHOPT_BGX
if((sh.sigflag[SIGCHLD]&SH_SIGTRAP) && sh.st.trapcom[SIGCHLD])
job_chldtrap(1);
diff --git a/src/cmd/ksh93/sh/jobs.c b/src/cmd/ksh93/sh/jobs.c
index 116ae3b..be333b2 100644
--- a/src/cmd/ksh93/sh/jobs.c
+++ b/src/cmd/ksh93/sh/jobs.c
@@ -1466,6 +1466,8 @@ int job_wait(pid_t pid)
continue;
if(nochild)
break;
+ if(sh.sigflag[SIGALRM]&SH_SIGTRAP)
+ sh_timetraps();
if((intr && sh.trapnote) || (pid==1 && !intr))
break;
}
diff --git a/src/cmd/ksh93/tests/builtins.sh b/src/cmd/ksh93/tests/builtins.sh
index 83b4086..92d2708 100755
--- a/src/cmd/ksh93/tests/builtins.sh
+++ b/src/cmd/ksh93/tests/builtins.sh
@@ -1222,6 +1222,28 @@ function test_usage
done 3< <(builtin)
}; test_usage
+# ======
+# The 'alarm' builtin could make 'read' crash due to IFS table corruption caused by unsafe asynchronous execution.
+# https://bugzilla.redhat.com/1176670
+if (builtin alarm) 2>/dev/null
+then got=$( { "$SHELL" -c '
+ builtin alarm
+ alarm -r alarm_handler +.005
+ i=0
+ function alarm_handler.alarm
+ {
+ let "(++i) > 20" && exit
+ }
+ while :; do
+ echo cargo,odds and ends,jetsam,junk,wreckage,castoffs,sea-drift
+ done | while IFS="," read arg1 arg2 arg3 arg4 junk; do
+ :
+ done
+ '; } 2>&1)
+ ((!(e = $?))) || err_exit 'crash with alarm and IFS' \
+ "(got status $e$( ((e>128)) && print -n /SIG && kill -l "$e"), $(printf %q "$got"))"
+fi
+
# ======
# Verify that the POSIX 'test' builtin exits with status 2 when given an invalid binary operator.
for operator in '===' ']]'
@@ -1581,7 +1603,7 @@ let Errors+=$?
# Most built-ins should handle --version
while IFS= read -r bltin <&3
do case $bltin in
- echo | test | true | false | \[ | : | catclose | catgets | catopen | Dt* | _Dt* | X* | login | newgrp )
+ alarm | echo | test | true | false | \[ | : | catclose | catgets | catopen | Dt* | _Dt* | X* | login | newgrp )
continue ;;
fc | hist )
((SHOPT_SCRIPTONLY)) && continue ;;

162
ksh-1.0.6-alarm-2.patch Normal file
View File

@ -0,0 +1,162 @@
diff --git a/src/cmd/ksh93/Mamfile b/src/cmd/ksh93/Mamfile
index abc9ee1a5..d266f2178 100644
--- a/src/cmd/ksh93/Mamfile
+++ b/src/cmd/ksh93/Mamfile
@@ -222,6 +222,10 @@ make install
prev shell.req
make alarm.o
make bltins/alarm.c
+ make include/io.h implicit
+ prev ${PACKAGE_ast_INCLUDE}/sfio.h
+ prev ${PACKAGE_ast_INCLUDE}/ast.h
+ done include/io.h
make FEATURE/time implicit
prev features/time
exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/time
@@ -239,6 +243,22 @@ make install
done FEATURE/dynamic generated
prev ${PACKAGE_ast_INCLUDE}/option.h
done include/builtins.h
+ make include/shlex.h implicit
+ make include/lexstates.h implicit
+ prev ${PACKAGE_ast_INCLUDE}/wctype.h
+ prev ${PACKAGE_ast_INCLUDE}/wchar.h
+ make FEATURE/locale implicit
+ prev features/locale
+ exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/locale
+ done FEATURE/locale generated
+ done include/lexstates.h
+ prev include/shtable.h
+ make include/shnodes.h implicit
+ prev include/argnod.h implicit
+ prev ${PACKAGE_ast_INCLUDE}/ast.h
+ done include/shnodes.h
+ prev ${PACKAGE_ast_INCLUDE}/cdt.h
+ done include/shlex.h
prev ${PACKAGE_ast_INCLUDE}/error.h
make include/defs.h implicit
prev include/regress.h implicit
@@ -246,7 +266,7 @@ make install
prev include/shell.h
prev ${PACKAGE_ast_INCLUDE}/endian.h
prev include/name.h
- prev include/argnod.h implicit
+ prev include/argnod.h
prev ${PACKAGE_ast_INCLUDE}/cdt.h
prev FEATURE/externs
prev ${PACKAGE_ast_INCLUDE}/error.h
@@ -292,10 +312,7 @@ make install
make cflow.o
make bltins/cflow.c
prev include/builtins.h
- make include/shnodes.h implicit
- prev include/argnod.h
- prev ${PACKAGE_ast_INCLUDE}/ast.h
- done include/shnodes.h
+ prev include/shnodes.h
prev ${PACKAGE_ast_INCLUDE}/error.h
prev ${PACKAGE_ast_INCLUDE}/ast.h
prev include/defs.h
@@ -341,10 +358,7 @@ make install
done FEATURE/ttys generated
done include/terminal.h
prev ${PACKAGE_ast_INCLUDE}/sig.h
- make FEATURE/locale implicit
- prev features/locale
- exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/locale
- done FEATURE/locale generated
+ prev FEATURE/locale
make FEATURE/cmds implicit
prev features/cmds
exec - iffe ${IFFEFLAGS} -v -c "${CC} ${mam_cc_FLAGS} ${CCFLAGS} ${LDFLAGS}" ref ${mam_cc_L+-L.} ${mam_cc_L+-L${INSTALLROOT}/lib} -I${PACKAGE_ast_INCLUDE} -I${INSTALLROOT}/include ${mam_libdll} ${mam_libcmd} ${mam_libast} ${mam_libm} ${mam_libnsl} : run features/cmds
@@ -353,6 +367,7 @@ make install
prev include/builtins.h
prev include/history.h
prev include/name.h
+ prev include/io.h
make include/io.h implicit
prev ${PACKAGE_ast_INCLUDE}/sfio.h
prev ${PACKAGE_ast_INCLUDE}/ast.h
@@ -443,11 +458,7 @@ make install
prev include/builtins.h
prev include/name.h
prev include/io.h
- make include/lexstates.h implicit
- prev ${PACKAGE_ast_INCLUDE}/wctype.h
- prev ${PACKAGE_ast_INCLUDE}/wchar.h
- prev FEATURE/locale
- done include/lexstates.h
+ prev include/lexstates.h
prev include/variables.h
prev include/defs.h
prev ${PACKAGE_ast_INCLUDE}/error.h
@@ -545,12 +556,7 @@ make install
make whence.o
make bltins/whence.c
prev include/builtins.h
- make include/shlex.h implicit
- prev include/lexstates.h
- prev include/shtable.h
- prev include/shnodes.h
- prev ${PACKAGE_ast_INCLUDE}/cdt.h
- done include/shlex.h
+ prev include/shlex.h
prev include/path.h
prev include/name.h
prev include/shtable.h
diff --git a/src/cmd/ksh93/bltins/alarm.c b/src/cmd/ksh93/bltins/alarm.c
index f31bed711..63d4d6cbf 100644
--- a/src/cmd/ksh93/bltins/alarm.c
+++ b/src/cmd/ksh93/bltins/alarm.c
@@ -23,21 +23,13 @@
*
*/
-/*
- * TODO: 2014 email from David Korn cited at <https://bugzilla.redhat.com/1176670>:
- *
- * > I never documented the alarm builtin because it is problematic. The
- * > problem is that traps can't safely be handled asynchronously. What should
- * > happen is that the trap is marked for execution (sh.trapnote) and run after
- * > the current command completes. The time trap should wake up the shell if
- * > it is blocked and it should return and then handle the trap.
- */
-
#include "shopt.h"
#include "defs.h"
#include <error.h>
+#include <shlex.h>
#include "builtins.h"
#include "FEATURE/time"
+#include "io.h"
#define R_FLAG 1
#define L_FLAG 2
@@ -147,7 +139,26 @@ void sh_timetraps(void)
{
tp->flags &= ~L_FLAG;
if(tp->action)
- sh_fun(tp->action,tp->node,NULL);
+ {
+ /* Call the alarm discipline function. This may occur at any time including parse time,
+ * so save the lexer state and push/pop context to make sure we can restore it. */
+ struct checkpt checkpoint;
+ int jmpval;
+ int savexit = sh.savexit;
+ Lex_t *lexp = (Lex_t*)sh.lex_context, savelex = *lexp;
+ sh_lexopen(lexp, 0); /* needs full init (0), not what it calls reinit (1) */
+ sh_pushcontext(&checkpoint, 1);
+ jmpval = sigsetjmp(checkpoint.buff,0);
+ if(!jmpval)
+ sh_fun(tp->action,tp->node,NULL);
+ sh_popcontext(&checkpoint);
+ if(sh.topfd != checkpoint.topfd)
+ sh_iorestore(checkpoint.topfd,jmpval);
+ *lexp = savelex;
+ sh.savexit = savexit; /* avoid influencing $? */
+ if(jmpval)
+ siglongjmp(*sh.jmplist,jmpval);
+ }
tp->flags &= ~L_FLAG;
if(!tp->flags)
nv_unset(tp->node);

View File

@ -1,7 +1,7 @@
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
Subject: [PATCH] Fix crash on failure to trim ~/.sh_history
@vmihalko writes:
> We were able to reproduce an old issue mentioned in
@ -40,16 +40,16 @@ src/cmd/ksh93/edit/history.c: hist_trim():
Resolves: https://github.com/ksh93/ksh/issues/695
---
src/cmd/ksh93/edit/history.c | 34 ++++------------------------------
1 file changed, 4 insertions(+), 30 deletions(-)
1 files 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
index c49c23244d00..f3672bf6e220 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;
@@ -419,34 +419,13 @@ static History_t* hist_trim(History_t *hp, int n)
char *cp;
int incmd=1, c=0;
History_t *hist_new, *hist_old = hp;
- char *buff, *endbuff, *tmpname=0;
+ char *buff, *endbuff;
off_t oldp,newp;
@ -58,34 +58,34 @@ index 1f6cd7c..0ed8e8a 100644
- if(access(hist_old->histname,F_OK) >= 0)
+ if(unlink(hist_old->histname) < 0)
{
- /* The unlink can fail on windows 95 */
- /* 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);
- sh_close(sffileno(hist_old->histfp));
- tmpname = (char*)sh_malloc(strlen(name)+14);
- if(last = strrchr(name,'/'))
- {
- *last = 0;
- pathtmp(tmpname,name,"hist",NIL(int*));
- pathtmp(tmpname,name,"hist",NULL);
- *last = '/';
- }
- else
- pathtmp(tmpname,".","hist",NIL(int*));
- pathtmp(tmpname,e_dot,"hist",NULL);
- if(rename(name,tmpname) < 0)
- {
- free(tmpname);
- tmpname = name;
- }
- fd = open(tmpname,O_RDONLY);
- fd = open(tmpname,O_RDONLY|O_cloexec);
- 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;
+ 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)
@@ -501,11 +480,6 @@ static History_t* hist_trim(History_t *hp, int n)
}
hist_cancel(hist_new);
sfclose(hist_old->histfp);
@ -97,6 +97,3 @@ index 1f6cd7c..0ed8e8a 100644
free((char*)hist_old);
return hist_ptr = hist_new;
}
--
2.42.0

View File

@ -31,23 +31,28 @@ src/cmd/ksh93/edit/history.c: sh_histinit():
[*] https://man7.org/linux/man-pages/man3/ttyname.3.html
---
src/cmd/ksh93/edit/history.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
src/cmd/ksh93/edit/history.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/src/cmd/ksh93/edit/history.c b/src/cmd/ksh93/edit/history.c
index de5e4a8..222d4bc 100644
index a7b084e5c16f..25832a59265b 100644
--- a/src/cmd/ksh93/edit/history.c
+++ b/src/cmd/ksh93/edit/history.c
@@ -395,7 +395,8 @@ retry:
@@ -15,6 +15,7 @@
* Johnothan King <johnothanking@protonmail.com> *
* hyenias <58673227+hyenias@users.noreply.github.com> *
* Govind Kamat <govind_kamat@yahoo.com> *
+* Vincent Mihalkovic <vmihalko@redhat.com> *
* *
***********************************************************************/
/*
@@ -353,7 +354,8 @@ int sh_histinit(void)
if(fd>=0)
{
fcntl(fd,F_SETFD,FD_CLOEXEC);
- hp->tty = strdup(ttyname(2));
- hp->tty = sh_strdup(isatty(2)?ttyname(2):"notty");
+ const char* tty = ttyname(2);
+ hp->tty = strdup(tty?tty:"notty");
hp->auditfp = sfnew((Sfio_t*)0,NULL,-1,fd,SF_WRITE);
+ hp->tty = sh_strdup(tty?tty:"notty");
hp->auditfp = sfnew(NULL,NULL,-1,fd,SF_WRITE);
}
}
--
2.43.0

View File

@ -0,0 +1,59 @@
From 26eec44e33ed4a48cb7ba34706d96387385d1980 Mon Sep 17 00:00:00 2001
From: Johnothan King <johnothanking@protonmail.com>
Date: Thu, 22 Feb 2024 15:26:57 -0800
Subject: [PATCH] Fix segfault on starting ksh with no TERM env var (#723)
This commit fixes a crash that prevented ksh from starting up in
single user mode on DragonFlyBSD and NetBSD.
src/cmd/ksh93/edit/edit.c:
- Make sure the np node for $TERM is not null before checking for
an export attribute.
Co-authored-by: Martijn Dekker <martijn@inlv.org>
Resolves: https://github.com/ksh93/ksh/issues/722
---
src/cmd/ksh93/edit/edit.c | 2 +-
src/cmd/ksh93/tests/pty.sh | 14 ++++++++++++++
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/src/cmd/ksh93/edit/edit.c b/src/cmd/ksh93/edit/edit.c
index 32e1e83..0ac54ba 100644
--- a/src/cmd/ksh93/edit/edit.c
+++ b/src/cmd/ksh93/edit/edit.c
@@ -614,7 +614,7 @@ void ed_setup(Edit_t *ep, int fd, int reedit)
static char *oldterm;
Namval_t *np = nv_search("TERM",sh.var_tree,0);
char *term = NULL;
- if(nv_isattr(np,NV_EXPORT))
+ if(np && nv_isattr(np,NV_EXPORT))
term = nv_getval(np);
if(!term)
term = "";
diff --git a/src/cmd/ksh93/tests/pty.sh b/src/cmd/ksh93/tests/pty.sh
index 5dbdf6c..b4f8e28 100755
--- a/src/cmd/ksh93/tests/pty.sh
+++ b/src/cmd/ksh93/tests/pty.sh
@@ -1255,5 +1255,19 @@ w _ksh_93u_m_cmdcompl\t
r :test-2: _ksh_93u_m_cmdcomplete_test_ \r\n$
!
+((multiline && (SHOPT_VSH || SHOPT_ESH))) && TERM=vt100 tst $LINENO <<"!"
+L crash when TERM is undefined
+# https://github.com/ksh93/ksh/issues/722
+
+d 40
+p :test-1:
+w unset TERM
+p :test-2:
+w "$SHELL"
+p :test-3:
+w print Exit status $?
+u ^Exit status 0\r\n$
+!
+
# ======
exit $((Errors<125?Errors:125))
--
2.49.0

View File

@ -0,0 +1,79 @@
diff --git a/src/cmd/ksh93/bltins/cflow.c b/src/cmd/ksh93/bltins/cflow.c
index b7cfd19..66e0f70 100644
--- a/src/cmd/ksh93/bltins/cflow.c
+++ b/src/cmd/ksh93/bltins/cflow.c
@@ -67,8 +67,12 @@ done:
{
long l = strtol(*argv, NULL, 10);
if(do_exit)
+ {
n = (int)(l & SH_EXITMASK); /* exit: apply bitmask before conversion to avoid undefined int overflow */
- else if((long)(n = (int)l) != l) /* return: convert to int and check for overflow (should be safe enough) */
+ if (sh.intrap)
+ sh.intrap_exit_n = 1;
+ }
+ else if((long)(n = (int)l) != l) /* return: convert to int and check for overflow (should be safe enough) */
{
errormsg(SH_DICT,ERROR_warn(0),"%s: out of range",*argv);
n = 128; /* overflow is undefined, so use a consistent status for this */
diff --git a/src/cmd/ksh93/include/shell.h b/src/cmd/ksh93/include/shell.h
index 9794995..58e2f2a 100644
--- a/src/cmd/ksh93/include/shell.h
+++ b/src/cmd/ksh93/include/shell.h
@@ -308,6 +308,7 @@ struct Shell_s
int savesig;
unsigned char *sigflag; /* pointer to signal states */
char intrap;
+ char intrap_exit_n; /* set if 'exit n' within trap */
char forked;
char binscript;
char funload;
diff --git a/src/cmd/ksh93/sh/fault.c b/src/cmd/ksh93/sh/fault.c
index 510bf56..8222a9d 100644
--- a/src/cmd/ksh93/sh/fault.c
+++ b/src/cmd/ksh93/sh/fault.c
@@ -528,11 +528,7 @@ int sh_trap(const char *trap, int mode)
if(jmpval==SH_JMPSCRIPT)
indone=0;
else
- {
- if(jmpval==SH_JMPEXIT)
- savxit = sh.exitval;
jmpval=SH_JMPTRAP;
- }
}
sh_popcontext(&buff);
/* re-allow last-command exec optimisation unless the command we executed set a trap */
@@ -541,8 +537,10 @@ int sh_trap(const char *trap, int mode)
sh.intrap--;
sfsync(sh.outpool);
savxit_return = sh.exitval;
- if(jmpval!=SH_JMPEXIT && jmpval!=SH_JMPFUN)
- sh.exitval=savxit;
+ if(sh.intrap_exit_n)
+ sh.intrap_exit_n = 0;
+ else
+ sh.exitval = savxit;
stkset(sh.stk,savptr,staktop);
fcrestore(&savefc);
if(was_history)
diff --git a/src/cmd/ksh93/tests/return.sh b/src/cmd/ksh93/tests/return.sh
index 25e4c7a..8db197b 100755
--- a/src/cmd/ksh93/tests/return.sh
+++ b/src/cmd/ksh93/tests/return.sh
@@ -247,5 +247,15 @@ foo && err_exit "'exit' within { block; } with redirection does not preserve exi
foo() { false; (exit); }
foo && err_exit "'exit' within subshell does not preserve exit status"
+# ======
+# old AT&T bug reintroduced in v1.0.8 (commit aea99158)
+f() { true; return; }
+trap 'f; echo $? >out' USR1
+(exit 13)
+kill -s USR1 ${.sh.pid}
+trap - USR1
+unset -f f
+[[ $(<out) == 0 ]] || err_exit "default return status in traps is broken (expected 0, got $(<out))"
+
# ======
exit $((Errors<125?Errors:125))

View File

@ -1,273 +1,70 @@
%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
Epoch: 3
Version: 1.0.6
Release: 12%{?dist}
Source0: https://github.com/ksh93/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz
Source1: kshcomp.conf
Source2: kshrc.rhs
Source3: dotkshrc
# expected results of test suite
Source5: expectedresults.log
# The alarm builtin hase been temporarily removed from ksh in version 1.0.0.
# To prevent customer regressions we revert following upstream commits:
# https://github.com/ksh93/ksh/commit/4d50b69cbd5fce91d1f3c527dc170e192ceb4760
# https://github.com/ksh93/ksh/commit/b369f40ded0ec7e8dd3d4a0e7226ccf037bb3400
# https://github.com/ksh93/ksh/commit/3688842b7291db6fccdb44ff8e99ab8d4c1b2508
Patch1: %{name}-1.0.6-alarm-1.patch
# alarm builtin was removed as it was unclear if it could ever be fixed
# alarm fixing patch from https://github.com/ksh93/ksh/issues/422#issuecomment-1581168550
Patch2: %{name}-1.0.6-alarm-2.patch
# don't use not wanted/needed builtins - Fedora/RHEL specific
Patch1: ksh-20070328-builtins.patch
#https://github.com/ksh93/ksh/commit/2075b2b96208ac8b989ca316dcdd674c3f488e2b
Patch3: %{name}-1.0.7-history-trim.patch
# fix regression test suite to be usable during packagebuild - Fedora/RHEL specific
Patch2: ksh-20100826-fixregr.patch
#upstream commit: https://github.com/ksh93/ksh/commit/9eb8532ccacf1cfdb7ba18f51eba68776852ef7c.patch
Patch4: ksh-1.0.7-segfault-strdup.patch
# fedora/rhel specific, rhbz#619692
Patch6: ksh-20080202-manfix.patch
#upstream commit: https://github.com/ksh93/ksh/commit/428c0917f3043358c9b54cc137a5037d69b01ed4
Patch5: ksh-1.0.9-trap-return-status.patch
# rhbz#702008
Patch17: ksh-20100202-pathvar.patch
#upstream commit: https://github.com/ksh93/ksh/commit/caae9aa23e2851cadf55f858a8f38b9f0de74314
Patch6: ksh-1.0.11-SHLVL.patch
# rhbz#924440
Patch18: ksh-20100621-fdstatus.patch
#upstream commit: https://github.com/ksh93/ksh/commit/5def43983de3ecfa38c805c02a1f0d6f1581160c
Patch7: ksh-1.0.11-redir.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
#upstream commit: https://github.com/ksh93/ksh/commit/6668c3eb0bdc48335120e7c48590ab46af0ef0f3
Patch8: ksh-1.0.10-pjob.patch
# for ksh <= 2013-05-31, rhbz#960034
Patch24: ksh-20120801-kshmfix.patch
#upstream commit: https://github.com/ksh93/ksh/commit/b15f63284bcd656729be61be6434376876be5bfc
#upstream commit: https://github.com/ksh93/ksh/commit/5e3a169785139809f1f733314f5660769c86d10c (test fix)
Patch9: ksh-1.0.9-no-TERM-env-segfault.patch
# for ksh <= 2016-06-28, rhbz#921455
Patch25: ksh-20120801-memlik.patch
# upstream commit: https://github.com/ksh93/ksh/commit/4350174a5d4acabf78f97b28c6d0ae68ec703e78
Patch10: ksh-1.0.11-stty-noecho.patch
# for ksh <= 2013-03-20, rhbz#922851
Patch26: ksh-20120801-forkbomb.patch
# upstream commit: https://github.com/ksh93/ksh/commit/96d73c08a2786806f3def1fda66641b81e0af988
Patch11: ksh-1.0.11-ssh-multibyte-long-paste.patch
# for ksh <= 2013-04-19, rhbz#913110
Patch27: ksh-20120801-macro.patch
# upstream commit: https://github.com/ksh93/ksh/commit/9f03b3bdb577ce74be3122d533c02830e3038e54
Patch12: ksh-1.0.11-segfault-sigwinch.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
# upstream commit: https://github.com/ksh93/ksh/commit/a1fcad4bf65fe26a3f9a386b63732ab151ce03ec
Patch13: ksh-1.0.10-blankline.patch
Conflicts: pdksh
Requires: coreutils, diffutils, chkconfig
Requires: coreutils, diffutils
BuildRequires: gcc
BuildRequires: bison
# regression test suite uses 'ps' from procps
BuildRequires: procps
Requires(post): grep, coreutils, systemd-units, chkconfig
Requires(post): grep, coreutils, systemd
Requires(postun): sed
Requires(preun): grep, coreutils, chkconfig
Provides: /bin/ksh
Provides: /bin/rksh
%description
KSH-93 is the most recent version of the KornShell by David Korn of
@ -276,34 +73,20 @@ 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
%autosetup -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
for f in -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 -Wno-maybe-uninitialized -Wno-lto-type-mismatch
do
gcc $f -E - </dev/null >/dev/null 2>&1 && XTRAFLAGS="$XTRAFLAGS $f"
$CC $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
export CCFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing $XTRAFLAGS"
export LDFLAGS="$RPM_LD_FLAGS"
./bin/package make
%install
mkdir -p %{buildroot}{/bin,%{_bindir},%{_mandir}/man1}
@ -311,41 +94,18 @@ 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
install -p -m 644 %{SOURCE3} %{buildroot}%{_sysconfdir}/skel/.kshrc
install -p -m 644 %{SOURCE2} %{buildroot}%{_sysconfdir}/kshrc
install -p -D -m 644 %{SOURCE1} %{buildroot}%{_sysconfdir}/binfmt.d/kshcomp.conf
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
touch %{buildroot}%{_bindir}/rksh
touch %{buildroot}%{_mandir}/man1/rksh.1.gz
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
%check
./bin/shtests --compile
%post
for s in /bin/ksh /bin/rksh /usr/bin/ksh /usr/bin/rksh
@ -361,6 +121,10 @@ done
%{_sbindir}/alternatives --install %{_bindir}/ksh ksh \
%{_bindir}/ksh93 50 \
--slave %{_bindir}/rksh rksh \
%{_bindir}/ksh93 \
--slave %{_mandir}/man1/rksh.1.gz rksh-man \
%{_mandir}/man1/ksh93.1.gz \
--slave %{_mandir}/man1/ksh.1.gz ksh-man \
%{_mandir}/man1/ksh93.1.gz
@ -372,14 +136,13 @@ if [ ! -L %{_bindir}/ksh ]; then
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
sed -i '\|^'"$s"'$|d' /etc/shells
fi
done
@ -397,93 +160,146 @@ else
echo "found"
fi
%files
%doc src/cmd/ksh93/COMPATIBILITY src/cmd/ksh93/RELEASE src/cmd/ksh93/TYPES
# LICENSE file is missing, temporarily?
%files
%doc src/cmd/ksh93/COMPATIBILITY src/cmd/ksh93/RELEASE src/cmd/ksh93/TYPES
%license LICENSE.md
%{_bindir}/ksh93
%ghost %{_bindir}/ksh
%{_bindir}/rksh
%ghost %{_bindir}/rksh
%{_bindir}/shcomp
%{_mandir}/man1/ksh93.1.gz
%{_mandir}/man1/*
%ghost %{_mandir}/man1/ksh.1.gz
%ghost %{_mandir}/man1/rksh.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
* Mon Jun 02 2025 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-12
- Fix recalling lines starting with whitespace
Resolves: RHEL-74464
* Thu Jan 25 2024 Lukáš Zaoral <lzaoral@redhat.com> - 20120801-266
- fix crashes when interrupting subshells (RHEL-11650)
* Mon May 19 2025 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-11
- Fix segfault upon SIGWINCH after 'stty -echo'
Resolves: RHEL-91097
* Wed Jan 03 2024 Vincent Mihalkovic <vmihalko@redhat.com> - 20120801-265
- Fix crash on failure to trim ~/.sh_history (RHEL-5685)
* Wed Apr 16 2025 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-10
- Fix long multibyte characters paste issue via ssh
Resolves: RHEL-87561
* Wed Nov 22 2023 Vincent Mihalkovic <vmihalko@redhat.com> - 20120801-264
- Remove broken monitor patch
* Mon Mar 31 2025 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-9
- Fix 'stty -echo' in scripts
Resolves: RHEL-83043
* Thu Nov 09 2023 Lukáš Zaoral <lzaoral@redhat.com> - 20120801-263
- fix UTF-8 quoting in xtrace
Resolves: RHEL-5684
* Sat Mar 29 2025 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-8
- Fix segfault on starting ksh with no TERM env var
Resolves: RHEL-83283
* Wed Nov 08 2023 Lukáš Zaoral <lzaoral@redhat.com> - 20120801-262
- fix segfault in subshell if $PATH contains a .paths directory
Resolves: RHEL-12011
* Mon Feb 17 2025 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-7
- Change p_job variable type from short to int
Resolves: RHEL-64299
* Tue Oct 31 2023 Lukáš Zaoral <lzaoral@redhat.com> - 20120801-261
* Wed Jan 22 2025 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-6
- Add forking workaround for block stdout redir
Resolves: RHEL-55913
* Mon Jan 13 2025 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-5
- Fix crash on 'exec' after 'unset SHLVL'
Resolves: RHEL-59656
* Tue Oct 01 2024 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-4
- Fix bad default 'return' status in traps
Resolves: RHEL-62228
* Sat Feb 10 2024 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-3
- Fix segfault in strdup
Resolves: RHEL-11982
Resolves: RHEL-25019
* Mon Sep 18 2023 Lukáš Zaoral <lzaoral@redhat.com> - 20120801-260
- Fix set +r so that it cannot unset the restricted option
Resolves: #1948588
* Wed Jan 03 2024 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-2
- Fix crash on failure to trim ~/.sh_history (#20345)
* Fri Aug 25 2023 Vincent Mihalkovic <vmihalko@redhat.com> - 20120801-259
- Fix crash on trying a very long command
Fix license tag
Resolves: #2013909
* Mon Sep 18 2023 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-1
- Rebase to non-beta version, because upstream says it should to be used
https://github.com/ksh93/ksh/issues/667#issuecomment-1653665697
- fix acl test case regression
Resolves: #2034188
* Wed Jul 26 2023 Vincent Mihalkovic <vmihalko@redhat.com> - 20120801-258
- disable vmalloc and force use of the operating system's malloc
Resolves: #2226653
* Tue Jun 27 2023 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.0~beta.1-3
- fix segfault when PWD is unset
Resolves: #2123066
* Mon Aug 08 2022 Vincent Mihalkovic <vmihalko@redhat.com> - 20120801-257
- Stack robustness fixes (two patches)
Resolves: #2116372
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 3:1.0.0~beta.1-2
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Thu Jul 21 2022 Vincent Mihalkovic <vmihalko@redhat.com> - 20120801-256
* Tue Aug 03 2021 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.0~BETA-1
- new upstream release
- remove upstreamed patches
- update CCFLAGS (https://github.com/ksh93/ksh/commit/98f989afcc7)
Resolves: #1986897
* Thu Jul 29 2021 Vincent Mihalkovic <vmihalko@redhat.com> - 2:20120801-258
- Fix license tag
Related: #1974805
* Wed Jul 28 2021 Vincent Mihalkovic <vmihalko@redhat.com> - 2:20120801-257
- Fix invalid source URLs
Resolves: #1974805
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 2:20120801-256
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Thu Mar 18 2021 Vincent Mihalkovic <vmihalko@redhat.com> - 2:20120801-255
- fix rksh-man in alternatives
* Tue Feb 23 2021 Vincent Mihalkovic <vmihalko@redhat.com> - 2:20120801-254
- Add alternatives switching for rksh
Resolves #1893919
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 2:20120801-253
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Fri Jan 22 2021 Vincent Mihalkovic <vmihalko@redhat.com> - 2:20120801-252
- Use set_build_flags and standard CC variables (commit: c488ab6)
* Thu Aug 13 2020 Siteshwar Vashisht <svashisht@redhat.com> - 2:20120801-251
- Restore ksh to version 20120801
Resolves: #1868715
* Tue Jul 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1:2020.0.0-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Fri Feb 07 2020 Siteshwar Vashisht <svashisht@redhat.com> - 1:2020.0.0-3
- Do not evaluate arithmetic expressions from environment variables at startup
Resolves: #2060600
Resolves: #1790549
* Mon Jan 03 2022 Vincent Mihalkovic <vmihalko@redhat.com> - 20120801-255
- Fix race conditions running external commands with job control on
Resolves: #1857847
* Wed Jan 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1:2020.0.0-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Thu Feb 06 2020 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-254
- Bump version number to avoid breaking upgrade path
* Fri Oct 11 2019 Siteshwar Vashisht <svashisht@redhat.com> - 1:2020.0.0-1
- Rebase to 2020.0.0
* Wed Jan 08 2020 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-253
- Do not evaluate arithmetic expressions from environment variables at startup
Resolves: #1790547
* Tue Sep 03 2019 Siteshwar Vashisht <svashisht@redhat.com> - 1:2020.0.0-0.4
- Rebase to 2020.0.0-beta1
* Tue Oct 16 2018 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-252
- Use autosetup instead of setup in spec file
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1:2020.0.0-0.3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Sun Oct 14 2018 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-251
- Add symlink for rksh
* Wed Apr 24 2019 Siteshwar Vashisht <svashisht@redhat.com> - 1:2020.0.0-0.2
- Add virtual provider for `/usr/bin/ksh`
* Sun Oct 14 2018 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-250
- Add alternatives switching with mksh
* Wed Apr 17 2019 Siteshwar Vashisht <svashisht@redhat.com> - 1:2020.0.0-0.1
- Rebase to 2020.0.0-alpha1
Resolves: #1700777
* Fri Oct 12 2018 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-249
- Fix annocheck failures
Resolves: #1624125
* Fri Feb 01 2019 Fedora Release Engineering <releng@fedoraproject.org> - 20120801-250
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Mon Aug 13 2018 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-248
- Fix several defects found by coverity
Resolves: #1610785
* Sun Oct 14 2018 Peter Robinson <pbrobinson@fedoraproject.org> 20120801-249
- chkconfig is no longer needed
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 20120801-248
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Mon Jun 04 2018 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-247
- Fix a crash caused by memcmp()

Some files were not shown because too many files have changed in this diff Show More