Compare commits

...

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

94 changed files with 3903 additions and 1027 deletions

View File

@ -1 +0,0 @@
1

65
.gitignore vendored
View File

@ -1,63 +1,2 @@
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
SOURCES/INIT.2012-08-01.tgz
SOURCES/ast-ksh.2012-08-01.tgz

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] Fix crash on failure to trim ~/.sh_history
Subject: [PATCH] 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 files changed, 4 insertions(+), 30 deletions(-)
1 file changed, 4 insertions(+), 30 deletions(-)
diff --git a/src/cmd/ksh93/edit/history.c b/src/cmd/ksh93/edit/history.c
index c49c23244d00..f3672bf6e220 100644
index 1f6cd7c..0ed8e8a 100644
--- a/src/cmd/ksh93/edit/history.c
+++ b/src/cmd/ksh93/edit/history.c
@@ -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;
@@ -461,34 +461,13 @@ static History_t* hist_trim(History_t *hp, int n)
register char *cp;
register int incmd=1, c=0;
register History_t *hist_new, *hist_old = hp;
- char *buff, *endbuff, *tmpname=0;
+ char *buff, *endbuff;
off_t oldp,newp;
@ -58,25 +58,25 @@ index c49c23244d00..f3672bf6e220 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;
- sh_close(sffileno(hist_old->histfp));
- tmpname = (char*)sh_malloc(strlen(name)+14);
- close(sffileno(hist_old->histfp));
- tmpname = (char*)malloc(strlen(name)+14);
- if(last = strrchr(name,'/'))
- {
- *last = 0;
- pathtmp(tmpname,name,"hist",NULL);
- pathtmp(tmpname,name,"hist",NIL(int*));
- *last = '/';
- }
- else
- pathtmp(tmpname,e_dot,"hist",NULL);
- pathtmp(tmpname,".","hist",NIL(int*));
- if(rename(name,tmpname) < 0)
- {
- free(tmpname);
- tmpname = name;
- }
- fd = open(tmpname,O_RDONLY|O_cloexec);
- fd = open(tmpname,O_RDONLY);
- sfsetfd(hist_old->histfp,fd);
- if(tmpname==name)
- tmpname = 0;
@ -85,7 +85,7 @@ index c49c23244d00..f3672bf6e220 100644
}
hist_ptr = 0;
if(fstat(sffileno(hist_old->histfp),&statb)>=0)
@@ -501,11 +480,6 @@ static History_t* hist_trim(History_t *hp, int n)
@@ -543,11 +522,6 @@ static History_t* hist_trim(History_t *hp, int n)
}
hist_cancel(hist_new);
sfclose(hist_old->histfp);
@ -97,3 +97,6 @@ index c49c23244d00..f3672bf6e220 100644
free((char*)hist_old);
return hist_ptr = hist_new;
}
--
2.42.0

View File

@ -0,0 +1,11 @@
diff -up ksh-20080202/src/cmd/ksh93/data/builtins.c.builtins ksh-20080202/src/cmd/ksh93/data/builtins.c
--- ksh-20080202/src/cmd/ksh93/data/builtins.c.builtins 2008-10-01 09:24:46.000000000 +0200
+++ ksh-20080202/src/cmd/ksh93/data/builtins.c 2008-10-01 09:24:58.000000000 +0200
@@ -129,7 +129,6 @@ const struct shtable3 shtab_builtins[] =
CMDLIST(dirname)
CMDLIST(getconf)
CMDLIST(head)
- CMDLIST(mkdir)
CMDLIST(logname)
CMDLIST(cat)
CMDLIST(cmp)

View File

@ -0,0 +1,47 @@
diff -up ksh-20120801/src/cmd/ksh93/sh.1.manfix ksh-20120801/src/cmd/ksh93/sh.1
--- ksh-20120801/src/cmd/ksh93/sh.1.manfix 2012-06-18 16:16:22.000000000 +0200
+++ ksh-20120801/src/cmd/ksh93/sh.1 2013-04-30 13:35:17.393909479 +0200
@@ -39,7 +39,7 @@ ksh93, rksh93, pfksh93 \- KornShell, a s
.B ksh93
.\}
[
-.B \(+-abcefhikmnoprstuvxBCDP
+.B \(+-abcefhiknoprstuvxBCDP
] [
.B \-R
file ] [
@@ -47,25 +47,6 @@ file ] [
option ] .\|.\|. [
.B \-
] [ arg .\|.\|. ]
-.br
-.if \nZ=0 \{\
-.B rsh
-.\}
-.if \nZ=1 \{\
-.B rksh
-.\}
-.if \nZ=2 \{\
-.B rksh93
-.\}
-[
-.B \(+-abcefhikmnoprstuvxBCD
-] [
-.B \-R
-file ] [
-.B \(+-o
-option ] .\|.\|. [
-.B \-
-] [ arg .\|.\|. ]
.SH DESCRIPTION
.if \nZ=0 .I Sh\^
.if \nZ=1 .I Ksh\^
@@ -7963,6 +7944,8 @@ option is used
to generate a cross reference database
that can be used by a separate utility
to find definitions and references for variables and commands.
+The filename argument specifies the generated database. A script file must be
+provided on the command line as well.
.PP
The remaining options and arguments are described under the
.B set

View File

@ -0,0 +1,20 @@
diff -up ksh-20100202/src/cmd/ksh93/sh.1.pathvar ksh-20100202/src/cmd/ksh93/sh.1
--- ksh-20100202/src/cmd/ksh93/sh.1.pathvar 2011-04-26 16:42:08.000000000 +0200
+++ ksh-20100202/src/cmd/ksh93/sh.1 2011-04-27 09:09:00.315883280 +0200
@@ -4025,13 +4025,9 @@ the directory containing the command.
Alternative directory names are separated by
a colon
.RB ( : ).
-The default path is
-.B /bin:/usr/bin:
-(specifying
-.BR /bin ,
-.BR /usr/bin ,
-and the current directory
-in that order).
+The default path is equal to
+.BI getconf\ PATH
+output.
The current directory can be specified by
two or more adjacent colons, or by a colon
at the beginning or end of the path list.

View File

@ -0,0 +1,54 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/io.c.fdstatus ksh-20120801/src/cmd/ksh93/sh/io.c
--- ksh-20120801/src/cmd/ksh93/sh/io.c.fdstatus 2013-07-04 18:01:27.187516655 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/io.c 2013-07-04 18:01:38.249607392 +0200
@@ -1508,7 +1508,7 @@ int sh_redirect(Shell_t *shp,struct iono
fn = fd;
if(fd<10)
{
- if((fn=fcntl(fd,F_DUPFD,10)) < 0)
+ if((fn=sh_fcntl(fd,F_DUPFD,10)) < 0)
goto fail;
if(fn>=shp->gd->lim.open_max && !sh_iovalidfd(shp,fn))
goto fail;
diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.fdstatus ksh-20120801/src/cmd/ksh93/sh/subshell.c
--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.fdstatus 2012-07-17 23:54:21.000000000 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2013-07-04 17:56:20.342000310 +0200
@@ -122,7 +122,7 @@ void sh_subtmpfile(Shell_t *shp)
register struct checkpt *pp = (struct checkpt*)shp->jmplist;
register struct subshell *sp = subshell_data->pipe;
/* save file descriptor 1 if open */
- if((sp->tmpfd = fd = fcntl(1,F_DUPFD,10)) >= 0)
+ if((sp->tmpfd = fd = sh_fcntl(1,F_DUPFD,10)) >= 0)
{
fcntl(fd,F_SETFD,FD_CLOEXEC);
shp->fdstatus[fd] = shp->fdstatus[1]|IOCLEX;
@@ -554,7 +554,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
sp->pwdfd = n;
if(n<10)
{
- sp->pwdfd = fcntl(n,F_DUPFD,10);
+ sp->pwdfd = sh_fcntl(n,F_DUPFD,10);
close(n);
}
if(sp->pwdfd>0)
diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.fdstatus ksh-20120801/src/cmd/ksh93/sh/xec.c
--- ksh-20120801/src/cmd/ksh93/sh/xec.c.fdstatus 2012-07-23 16:49:32.000000000 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2013-07-04 17:57:47.153712116 +0200
@@ -116,7 +116,7 @@ static int iousepipe(Shell_t *shp)
return(0);
usepipe++;
fcntl(subpipe[0],F_SETFD,FD_CLOEXEC);
- subpipe[2] = fcntl(1,F_DUPFD,10);
+ subpipe[2] = sh_fcntl(1,F_DUPFD,10);
fcntl(subpipe[2],F_SETFD,FD_CLOEXEC);
shp->fdstatus[subpipe[2]] = shp->fdstatus[1];
close(1);
@@ -3622,7 +3622,7 @@ static void coproc_init(Shell_t *shp, in
sh_pipe(shp->cpipe);
if((outfd=shp->cpipe[1]) < 10)
{
- int fd=fcntl(shp->cpipe[1],F_DUPFD,10);
+ int fd=sh_fcntl(shp->cpipe[1],F_DUPFD,10);
if(fd>=10)
{
shp->fdstatus[fd] = (shp->fdstatus[outfd]&~IOCLEX);

View File

@ -0,0 +1,12 @@
diff -up ksh-20100621/src/cmd/ksh93/sh.1.manfix3 ksh-20100621/src/cmd/ksh93/sh.1
--- ksh-20100621/src/cmd/ksh93/sh.1.manfix3 2013-05-02 13:07:51.180529762 +0200
+++ ksh-20100621/src/cmd/ksh93/sh.1 2013-05-02 13:11:30.469327199 +0200
@@ -7585,7 +7585,7 @@ file descriptor 2.
If the
.B \-i
option is present or
-if the shell input and output are attached to a terminal (as told by
+if the shell input and error output are attached to a terminal (as told by
.IR tcgetattr (2)),
then this shell is
.IR interactive .

View File

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

View File

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

View File

@ -0,0 +1,33 @@
--- ksh-20120801/src/cmd/ksh93/sh/init.c 2014-12-10 20:11:17.693446084 -0200
+++ ksh-20120801/src/cmd/ksh93/sh/init.c 2014-12-10 20:11:24.753442619 -0200
@@ -576,6 +576,7 @@ static char* get_ifs(register Namval_t*
shp->ifstable[' '] = shp->ifstable['\t'] = S_SPACE;
shp->ifstable['\n'] = S_NL;
}
+ shp->ifstable[0] = S_EOF;
}
return(value);
}
--- ksh-20120801/src/cmd/ksh93/bltins/alarm.c 2014-12-18 12:03:39.198461933 -0200
+++ ksh-20120801/src/cmd/ksh93/bltins/alarm.c 2014-12-18 12:04:32.464421268 -0200
@@ -130,6 +130,7 @@ void sh_timetraps(Shell_t *shp)
{
register struct tevent *tp, *tpnext;
register struct tevent *tptop;
+ char ifstable[256];
while(1)
{
shp->sigflag[SIGALRM] &= ~SH_SIGALRM;
@@ -141,7 +142,11 @@ void sh_timetraps(Shell_t *shp)
{
tp->flags &= ~L_FLAG;
if(tp->action)
+ {
+ memcpy(ifstable,shp->ifstable,sizeof(ifstable));
sh_fun(tp->action,tp->node,(char**)0);
+ memcpy(shp->ifstable,ifstable,sizeof(ifstable));
+ }
tp->flags &= ~L_FLAG;
if(!tp->flags)
{

View File

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

View File

@ -0,0 +1,13 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/main.c.fixargs ksh-20120801/src/cmd/ksh93/sh/main.c
--- ksh-20120801/src/cmd/ksh93/sh/main.c.fixargs 2013-12-31 11:32:14.917874134 +0100
+++ ksh-20120801/src/cmd/ksh93/sh/main.c 2013-12-31 11:32:58.028847126 +0100
@@ -757,7 +757,7 @@ static void fixargs(char **argv, int mod
offset += size;
buff[offset++] = ' ';
}
- buff[offset-1] = 0;
+ memset(&buff[offset - 1], 0, command_len - offset + 1);
# ifdef PSTAT
un.pst_command = stakptr(0);
pstat(PSTAT_SETCMD,un,0,0,0);

View File

@ -0,0 +1,20 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/name.c.orig ksh-20120801/src/cmd/ksh93/sh/name.c
--- ksh-20120801/src/cmd/ksh93/sh/name.c.orig 2015-02-10 17:15:37.180783550 -0200
+++ ksh-20120801/src/cmd/ksh93/sh/name.c 2015-02-10 18:25:51.726228437 -0200
@@ -1298,7 +1298,16 @@ void nv_delete(Namval_t* np, Dt_t *root,
if(dtdelete(root,np))
{
if(!(flags&NV_NOFREE) && ((flags&NV_FUNCTION) || !nv_subsaved(np,flags&NV_TABLE)))
+ {
+ Namarr_t *ap;
+ if(nv_isarray(np) && np->nvfun && (ap=nv_arrayptr(np)) && array_assoc(ap)) {
+ while(nv_associative(np,0,NV_ANEXT))
+ nv_associative(np, 0, NV_ADELETE);
+ nv_associative(np, 0, NV_AFREE);
+ free((void*)np->nvfun);
+ }
free((void*)np);
+ }
}
#if 0
else

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,12 @@
diff -up ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.cdfix3 ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c
--- ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.cdfix3 2014-06-20 12:39:02.757407689 +0200
+++ ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c 2014-06-20 12:40:19.530998070 +0200
@@ -290,7 +290,7 @@ int b_cd(int argc, char *argv[],Shbltin_
if(newdirfd >=0)
{
/* chdir for directories on HSM/tapeworms may take minutes */
- if(fchdir(newdirfd) >= 0)
+ if((rval=fchdir(newdirfd)) >= 0)
{
if(shp->pwdfd >= 0)
sh_close(shp->pwdfd);

View File

@ -0,0 +1,40 @@
--- ksh-20120801/src/cmd/ksh93/sh/path.c 2014-09-01 15:08:06.738969962 -0300
+++ ksh-20120801/src/cmd/ksh93/sh/path.c 2014-09-01 15:13:51.321459978 -0300
@@ -229,13 +229,12 @@ static pid_t path_xargs(Shell_t *shp,con
/*
* make sure PWD is set up correctly
* Return the present working directory
- * Invokes getcwd() if flag==0 and if necessary
+ * Invokes getcwd() if necessary
* Sets the PWD variable to this value
*/
char *path_pwd(Shell_t *shp,int flag)
{
register char *cp;
- register char *dfault = (char*)e_dot;
register int count = 0;
if(shp->pwd)
return((char*)shp->pwd);
@@ -254,11 +253,6 @@ char *path_pwd(Shell_t *shp,int flag)
cp = "/";
break;
case 3:
- cp = (char*)e_crondir;
- if(flag) /* skip next case when non-zero flag */
- ++count;
- break;
- case 4:
{
if(cp=getcwd(NIL(char*),0))
{
@@ -269,8 +263,8 @@ char *path_pwd(Shell_t *shp,int flag)
}
break;
}
- case 5:
+ case 4:
- return(dfault);
+ return((char*)e_dot);
}
if(cp && *cp=='/' && test_inode(cp,e_dot))
break;

View File

@ -0,0 +1,58 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/init.c.covsfix ksh-20120801/src/cmd/ksh93/sh/init.c
--- ksh-20120801/src/cmd/ksh93/sh/init.c.covsfix 2013-07-22 17:41:34.674054068 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/init.c 2013-07-22 17:42:50.761361921 +0200
@@ -1237,9 +1237,11 @@ static void put_mode(Namval_t* np, const
mode = *(double*)val;
}
else
+ {
mode = strperm(val, &last,0);
- if(*last)
- errormsg(SH_DICT,ERROR_exit(1),"%s: invalid mode string",val);
+ if(*last)
+ errormsg(SH_DICT,ERROR_exit(1),"%s: invalid mode string",val);
+ }
nv_putv(np,(char*)&mode,NV_INTEGER,nfp);
}
else
diff -up ksh-20120801/src/cmd/ksh93/sh/io.c.covsfix ksh-20120801/src/cmd/ksh93/sh/io.c
--- ksh-20120801/src/cmd/ksh93/sh/io.c.covsfix 2013-07-22 17:06:30.282927080 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/io.c 2013-07-22 17:08:49.645721280 +0200
@@ -954,6 +954,7 @@ int sh_pipe(register int pv[])
socklen_t slen;
if ((pv[out] = socket (AF_INET, SOCK_STREAM, 0)) < 0)
errormsg(SH_DICT,ERROR_system(1),e_pipe);
+ memset(&sin.sin_zero, 0, sizeof(sin.sin_zero));
do
{
sin.sin_family = AF_INET;
diff -up ksh-20120801/src/cmd/ksh93/sh/name.c.covsfix ksh-20120801/src/cmd/ksh93/sh/name.c
--- ksh-20120801/src/cmd/ksh93/sh/name.c.covsfix 2013-07-22 17:40:31.644635604 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/name.c 2013-07-22 17:41:15.828227073 +0200
@@ -3094,6 +3094,7 @@ void nv_newattr (register Namval_t *np,
if(!mp)
nv_putval (np, cp, NV_RDONLY);
free(cp);
+ cp = NULL;
}
}
while(ap && nv_nextsub(np));
diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.covsfix ksh-20120801/src/cmd/ksh93/sh/subshell.c
--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.covsfix 2013-07-22 17:46:15.607533423 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2013-07-22 17:48:36.739290968 +0200
@@ -205,7 +205,14 @@ void sh_subfork(void)
shp->comsub = 0;
SH_SUBSHELLNOD->nvalue.s = 0;
sp->subpid=0;
- shp->st.trapcom[0] = (comsub==2?NULL:trap);
+ if (comsub==2)
+ {
+ shp->st.trapcom[0] = NULL;
+ if(trap)
+ free((void*)trap);
+ }
+ else
+ shp->st.trapcom[0] = (comsub==2?NULL:trap);
shp->savesig = 0;
}
}

View File

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

View File

@ -0,0 +1,64 @@
diff -up ksh-20120801/src/cmd/ksh93/include/jobs.h.crash ksh-20120801/src/cmd/ksh93/include/jobs.h
--- ksh-20120801/src/cmd/ksh93/include/jobs.h.crash 2014-07-22 11:48:57.205062905 +0200
+++ ksh-20120801/src/cmd/ksh93/include/jobs.h 2014-07-22 11:48:57.243062711 +0200
@@ -118,6 +118,7 @@ struct jobs
char jobcontrol; /* turned on for real job control */
char waitsafe; /* wait will not block */
char waitall; /* wait for all jobs in pipe */
+ char hack1_waitall;
char toclear; /* job table needs clearing */
unsigned char *freejobs; /* free jobs numbers */
#if SHOPT_COSHELL
diff -up ksh-20120801/src/cmd/ksh93/sh/jobs.c.crash ksh-20120801/src/cmd/ksh93/sh/jobs.c
--- ksh-20120801/src/cmd/ksh93/sh/jobs.c.crash 2014-07-22 11:48:57.190062982 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/jobs.c 2014-07-22 11:48:57.243062711 +0200
@@ -1957,6 +1957,7 @@ again:
{
count = bp->count;
jp = bp->list;
+ jpold = 0;
goto again;
}
if(jp)
diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.crash ksh-20120801/src/cmd/ksh93/sh/subshell.c
--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.crash 2014-07-22 11:48:57.234062758 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2014-07-22 11:54:04.164491483 +0200
@@ -492,6 +492,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
struct sh_scoped savst;
struct dolnod *argsav=0;
int argcnt;
+ int pipefail = 0;
memset((char*)sp, 0, sizeof(*sp));
sfsync(shp->outpool);
sh_sigcheck(shp);
@@ -541,7 +542,10 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
sp->comsub = shp->comsub;
shp->subshare = comsub==2 || (comsub==1 && sh_isoption(SH_SUBSHARE));
if(comsub)
+ {
shp->comsub = comsub;
+ job.hack1_waitall=(comsub==1);
+ }
sp->shpwdfd=-1;
if(!comsub || !shp->subshare)
{
@@ -648,6 +652,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
}
else
{
+ job.hack1_waitall=0;
if(comsub!=1 && shp->spid)
{
job_wait(shp->spid);
diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.crash ksh-20120801/src/cmd/ksh93/sh/xec.c
--- ksh-20120801/src/cmd/ksh93/sh/xec.c.crash 2014-07-22 11:48:57.228062787 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2014-07-22 11:48:57.245062700 +0200
@@ -2125,7 +2125,7 @@ int sh_exec(register const Shnode_t *t,
memset(exitval,0,job.waitall*sizeof(int));
}
else
- job.waitall |= !pipejob && sh_isstate(SH_MONITOR);
+ job.waitall |= job.hack1_waitall || !pipejob && sh_isstate(SH_MONITOR);
job_lock();
nlock++;
do

View File

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

View File

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

View File

@ -0,0 +1,11 @@
--- ksh-20120801/src/cmd/ksh93/sh/array.c 2014-12-11 16:39:34.253860675 -0200
+++ ksh-20120801/src/cmd/ksh93/sh/array.c 2014-12-11 16:39:40.794857083 -0200
@@ -1003,7 +1003,7 @@ Namarr_t *nv_setarray(Namval_t *np, void
ap->nelem = nelem;
ap->fun = fun;
nv_onattr(np,NV_ARRAY);
- if(fp || value)
+ if(fp || (value && value != Empty))
{
nv_putsub(np, "0", ARRAY_ADD);
if(value)

View File

@ -0,0 +1,72 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/macro.c.fd2lost ksh-20120801/src/cmd/ksh93/sh/macro.c
--- ksh-20120801/src/cmd/ksh93/sh/macro.c.fd2lost 2014-01-22 16:23:21.211658984 +0100
+++ ksh-20120801/src/cmd/ksh93/sh/macro.c 2014-01-22 16:23:21.243658703 +0100
@@ -391,7 +391,7 @@ void sh_machere(Shell_t *shp,Sfio_t *inf
break;
}
case S_PAR:
- comsubst(mp,(Shnode_t*)0,1);
+ comsubst(mp,(Shnode_t*)0,3);
break;
case S_EOF:
if((c=fcfill()) > 0)
@@ -1165,7 +1165,7 @@ retry1:
case S_PAR:
if(type)
goto nosub;
- comsubst(mp,(Shnode_t*)0,1);
+ comsubst(mp,(Shnode_t*)0,3);
return(1);
case S_DIG:
var = 0;
diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.fd2lost ksh-20120801/src/cmd/ksh93/sh/subshell.c
--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.fd2lost 2014-01-22 16:23:21.222658887 +0100
+++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2014-01-22 16:23:21.243658703 +0100
@@ -122,7 +122,8 @@ void sh_subtmpfile(Shell_t *shp)
else if(errno!=EBADF)
errormsg(SH_DICT,ERROR_system(1),e_toomany);
/* popping a discipline forces a /tmp file create */
- sfdisc(sfstdout,SF_POPDISC);
+ if(shp->comsub != 1)
+ sfdisc(sfstdout,SF_POPDISC);
if((fd=sffileno(sfstdout))<0)
{
/* unable to create the /tmp file so use a pipe */
@@ -635,6 +636,13 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
}
else
{
+ if(comsub!=1 && shp->spid)
+ {
+ job_wait(shp->spid);
+ if(shp->pipepid==shp->spid)
+ shp->spid = 0;
+ shp->pipepid = 0;
+ }
/* move tmp file to iop and restore sfstdout */
iop = sfswap(sfstdout,NIL(Sfio_t*));
if(!iop)
diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.fd2lost ksh-20120801/src/cmd/ksh93/sh/xec.c
--- ksh-20120801/src/cmd/ksh93/sh/xec.c.fd2lost 2014-01-22 16:23:21.237658756 +0100
+++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2014-01-22 16:38:36.374666019 +0100
@@ -1756,6 +1756,8 @@ int sh_exec(register const Shnode_t *t,
nlock--;
job_unlock();
}
+ if(shp->subshell)
+ shp->spid = parent;
if(type&FPCL)
sh_close(shp->inpipe[0]);
if(type&(FCOOP|FAMP))
@@ -1771,7 +1773,11 @@ int sh_exec(register const Shnode_t *t,
if(shp->pipepid)
shp->pipepid = parent;
else
+ {
job_wait(parent);
+ if(parent==shp->spid)
+ shp->spid = 0;
+ }
if(shp->topfd > topfd)
sh_iorestore(shp,topfd,0);
if(usepipe && tsetio && subdup && unpipe)

View File

@ -0,0 +1,11 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/io.c.tryfix01 ksh-20120801/src/cmd/ksh93/sh/io.c
--- ksh-20120801/src/cmd/ksh93/sh/io.c.tryfix01 2014-02-26 16:15:52.355391420 +0100
+++ ksh-20120801/src/cmd/ksh93/sh/io.c 2014-02-26 16:23:55.588148801 +0100
@@ -1326,6 +1326,7 @@ int sh_redirect(Shell_t *shp,struct iono
if(flag==SH_SHOWME)
goto traceit;
fd=sh_chkopen(fname);
+ fd=sh_iomovefd(fd);
}
else if(sh_isoption(SH_RESTRICTED))
errormsg(SH_DICT,ERROR_exit(1),e_restricted,fname);

View File

@ -0,0 +1,12 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/fault.c.forkbomb ksh-20120801/src/cmd/ksh93/sh/fault.c
--- ksh-20120801/src/cmd/ksh93/sh/fault.c.forkbomb 2013-04-30 16:20:40.237490109 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/fault.c 2013-04-30 16:21:49.961068778 +0200
@@ -519,7 +519,7 @@ void sh_exit(register int xno)
if(pp && pp->mode>1)
cursig = -1;
#ifdef SIGTSTP
- if(shp->trapnote&SH_SIGTSTP)
+ if((shp->trapnote&SH_SIGTSTP) && job.jobcontrol)
{
/* ^Z detected by the shell */
shp->trapnote = 0;

View File

@ -0,0 +1,12 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.fununset ksh-20120801/src/cmd/ksh93/sh/xec.c
--- ksh-20120801/src/cmd/ksh93/sh/xec.c.fununset 2014-06-16 14:21:09.293513844 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2014-06-16 14:21:09.309513760 +0200
@@ -3570,7 +3570,7 @@ static void sh_funct(Shell_t *shp,Namval
#endif
nv_putval(SH_PATHNAMENOD,shp->st.filename,NV_NOFREE);
shp->pipepid = pipepid;
- np->nvalue.rp->running -= 2;
+ if (np->nvalue.rp) np->nvalue.rp->running -= 2;
}
/*

View File

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

View File

@ -0,0 +1,32 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/lex.c.heresub ksh-20120801/src/cmd/ksh93/sh/lex.c
--- ksh-20120801/src/cmd/ksh93/sh/lex.c.heresub 2014-05-21 16:48:42.635700984 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/lex.c 2014-05-21 16:48:42.678700772 +0200
@@ -1557,6 +1557,7 @@ static int comsub(register Lex_t *lp, in
{
register int n,c,count=1;
register int line=lp->sh->inlineno;
+ struct ionod *inheredoc = lp->heredoc;
char *first,*cp=fcseek(0),word[5];
int off, messages=0, assignok=lp->assignok, csub;
struct lexstate save;
@@ -1683,7 +1684,7 @@ done:
lp->lexd.dolparen--;
lp->lex = save;
lp->assignok = (endchar(lp)==RBRACT?assignok:0);
- if(lp->heredoc)
+ if(lp->heredoc && !inheredoc)
errormsg(SH_DICT,ERROR_exit(SYNBAD),e_lexsyntax5,lp->sh->inlineno,lp->heredoc->ioname);
return(messages);
}
diff -up ksh-20120801/src/cmd/ksh93/sh/macro.c.heresub ksh-20120801/src/cmd/ksh93/sh/macro.c
--- ksh-20120801/src/cmd/ksh93/sh/macro.c.heresub 2014-05-21 16:48:42.650700910 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/macro.c 2014-05-21 16:48:42.678700772 +0200
@@ -2085,7 +2085,7 @@ static void comsubst(Mac_t *mp,register
}
sfputc(stkp,c);
}
- sfputc(stkp,' ');
+ sfputc(stkp,'\n');
c = stktell(stkp);
str=stkfreeze(stkp,1);
/* disable verbose and don't save in history file */

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,66 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/main.c.monintoron ksh-20120801/src/cmd/ksh93/sh/main.c
--- ksh-20120801/src/cmd/ksh93/sh/main.c.monintoron 2013-05-31 10:15:02.738828102 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/main.c 2013-05-31 10:15:36.057095262 +0200
@@ -406,10 +406,10 @@ static void exfile(register Shell_t *shp
{
buff.mode = SH_JMPEXIT;
sh_onoption(SH_TRACKALL);
- sh_offoption(SH_MONITOR);
}
sh_offstate(SH_INTERACTIVE);
- sh_offstate(SH_MONITOR);
+ if(sh_isoption(SH_MONITOR))
+ sh_onstate(SH_MONITOR);
sh_offstate(SH_HISTORY);
sh_offoption(SH_HISTORY);
}
diff -up ksh-20120801/src/cmd/ksh93/sh/jobs.c.orig ksh-20120801/src/cmd/ksh93/sh/jobs.c
--- ksh-20120801/src/cmd/ksh93/sh/jobs.c.orig 2013-05-31 10:12:28.358590452 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/jobs.c 2013-05-31 10:16:51.203697890 +0200
@@ -548,7 +548,7 @@ int job_reap(register int sig)
{
px = job_byjid((int)pw->p_job);
for(; px && (px->p_flag&P_DONE); px=px->p_nxtproc);
- if(!px)
+ if(!px && sh_isoption(SH_INTERACTIVE))
tcsetpgrp(JOBTTY,job.mypid);
}
#ifndef SHOPT_BGX
@@ -842,10 +842,11 @@ static void job_set(register struct proc
static void job_reset(register struct process *pw)
{
+ Shell_t *shp = pw->p_shp;
/* save the terminal state for current job */
#ifdef SIGTSTP
job_fgrp(pw,tcgetpgrp(job.fd));
- if(tcsetpgrp(job.fd,job.mypid) !=0)
+ if(sh_isoption(SH_INTERACTIVE) && tcsetpgrp(job.fd,job.mypid) !=0)
return;
#endif /* SIGTSTP */
/* force the following tty_get() to do a tcgetattr() unless fg */
diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.orig ksh-20120801/src/cmd/ksh93/sh/xec.c
--- ksh-20120801/src/cmd/ksh93/sh/xec.c.orig 2013-05-31 10:12:27.000000000 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2013-05-31 10:18:14.650367185 +0200
@@ -2201,7 +2201,7 @@ int sh_exec(register const Shnode_t *t,
}
shp->exitval = n;
#ifdef SIGTSTP
- if(!pipejob && sh_isstate(SH_MONITOR))
+ if(!pipejob && sh_isstate(SH_MONITOR) && sh_isoption(SH_INTERACTIVE))
tcsetpgrp(JOBTTY,shp->gd->pid);
#endif /*SIGTSTP */
job.curpgid = savepgid;
diff -up ksh-20120801/src/cmd/ksh93/edit/edit.c.kshmfix ksh-20120801/src/cmd/ksh93/edit/edit.c
--- ksh-20120801/src/cmd/ksh93/edit/edit.c.kshmfix 2013-09-23 10:46:57.007256192 +0200
+++ ksh-20120801/src/cmd/ksh93/edit/edit.c 2013-09-23 10:47:43.988937610 +0200
@@ -1050,7 +1050,7 @@ int ed_getchar(register Edit_t *ep,int m
{
if(mode<=0 && -c == ep->e_intr)
{
- sh_fault(SIGINT);
+ killpg(getpgrp(),SIGINT);
siglongjmp(ep->e_env, UINTR);
}
if(mode<=0 && ep->sh->st.trap[SH_KEYTRAP])

View File

@ -0,0 +1,56 @@
diff -up ksh-20120801/src/cmd/ksh93/edit/edit.c.trajfiks ksh-20120801/src/cmd/ksh93/edit/edit.c
--- ksh-20120801/src/cmd/ksh93/edit/edit.c.trajfiks 2012-08-02 00:18:19.000000000 +0200
+++ ksh-20120801/src/cmd/ksh93/edit/edit.c 2014-02-06 12:12:11.570942651 +0100
@@ -53,6 +53,7 @@
static char CURSOR_UP[20] = { ESC, '[', 'A', 0 };
static char KILL_LINE[20] = { ESC, '[', 'J', 0 };
+static char *savelex;
@@ -232,6 +233,8 @@ int tty_set(int fd, int action, struct t
void tty_cooked(register int fd)
{
register Edit_t *ep = (Edit_t*)(shgd->ed_context);
+ if(ep->sh->st.trap[SH_KEYTRAP] && savelex)
+ memcpy(ep->sh->lex_context,savelex,ep->sh->lexsize);
ep->e_keytrap = 0;
if(ep->e_raw==0)
return;
@@ -783,6 +786,13 @@ void ed_setup(register Edit_t *ep, int f
ep->e_lbuf[n] = *pp++;
ep->e_default = 0;
}
+ if(ep->sh->st.trap[SH_KEYTRAP])
+ {
+ if(!savelex)
+ savelex = (char*)malloc(shp->lexsize);
+ if(savelex)
+ memcpy(savelex, ep->sh->lex_context, ep->sh->lexsize);
+ }
}
static void ed_putstring(register Edit_t *ep, const char *str)
diff -up ksh-20120801/src/cmd/ksh93/include/defs.h.trajfiks ksh-20120801/src/cmd/ksh93/include/defs.h
--- ksh-20120801/src/cmd/ksh93/include/defs.h.trajfiks 2014-02-06 12:18:13.149091836 +0100
+++ ksh-20120801/src/cmd/ksh93/include/defs.h 2014-02-06 12:18:13.175091784 +0100
@@ -224,6 +224,7 @@ struct shared
int xargexit; \
int nenv; \
mode_t mask; \
+ int lexsize; \
Env_t *env; \
void *init_context; \
void *mac_context; \
diff -up ksh-20120801/src/cmd/ksh93/sh/lex.c.trajfiks ksh-20120801/src/cmd/ksh93/sh/lex.c
--- ksh-20120801/src/cmd/ksh93/sh/lex.c.trajfiks 2014-02-06 12:19:13.587950320 +0100
+++ ksh-20120801/src/cmd/ksh93/sh/lex.c 2014-02-06 12:19:13.623950219 +0100
@@ -268,6 +268,7 @@ Lex_t *sh_lexopen(Lex_t *lp, Shell_t *sp
{
lp = (Lex_t*)newof(0,Lex_t,1,0);
lp->sh = sp;
+ sp->lexsize = sizeof(Lex_t);
}
fcnotify(lex_advance,lp);
lp->lex.intest = lp->lex.incase = lp->lex.skipword = lp->lexd.warn = 0;

View File

@ -0,0 +1,26 @@
diff -up ksh-20120801/src/cmd/ksh93/include/jobs.h.locking ksh-20120801/src/cmd/ksh93/include/jobs.h
--- ksh-20120801/src/cmd/ksh93/include/jobs.h.locking 2014-06-27 15:51:07.144923719 +0200
+++ ksh-20120801/src/cmd/ksh93/include/jobs.h 2014-06-27 15:52:56.463272276 +0200
@@ -149,15 +149,18 @@ extern struct jobs job;
#define vmbusy() 0
#endif
-#define job_lock() (job.in_critical++)
+#define asoincint(p) __sync_fetch_and_add(p,1)
+#define asodecint(p) __sync_fetch_and_sub(p,1)
+
+#define job_lock() asoincint(&job.in_critical)
#define job_unlock() \
do { \
int sig; \
- if (!--job.in_critical && (sig = job.savesig)) \
+ if (asodecint(&job.in_critical)==1 && (sig = job.savesig)) \
{ \
- if (!job.in_critical++ && !vmbusy()) \
+ if (!asoincint(&job.in_critical) && !vmbusy()) \
job_reap(sig); \
- job.in_critical--; \
+ asodecint(&job.in_critical); \
} \
} while(0)

View File

@ -0,0 +1,178 @@
diff -up ksh-20120801/src/cmd/ksh93/include/io.h.macro ksh-20120801/src/cmd/ksh93/include/io.h
--- ksh-20120801/src/cmd/ksh93/include/io.h.macro 2012-07-18 16:12:38.000000000 +0200
+++ ksh-20120801/src/cmd/ksh93/include/io.h 2013-07-04 16:14:05.809595966 +0200
@@ -81,6 +81,7 @@ extern void sh_iosave(Shell_t *, int,in
extern int sh_iovalidfd(Shell_t*, int);
extern int sh_inuse(Shell_t*, int);
extern void sh_iounsave(Shell_t*);
+extern void iounpipe(Shell_t*);
extern int sh_chkopen(const char*);
extern int sh_ioaccess(int,int);
extern int sh_devtofd(const char*);
diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.macro ksh-20120801/src/cmd/ksh93/sh/subshell.c
--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.macro 2013-07-04 16:14:05.783595751 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2013-07-04 16:15:46.673432991 +0200
@@ -171,7 +171,7 @@ void sh_subfork(void)
{
register struct subshell *sp = subshell_data;
Shell_t *shp = sp->shp;
- int curenv = shp->curenv;
+ int curenv = shp->curenv, comsub=shp->comsub;
pid_t pid;
char *trap = shp->st.trapcom[0];
if(trap)
@@ -204,7 +204,7 @@ void sh_subfork(void)
shp->comsub = 0;
SH_SUBSHELLNOD->nvalue.s = 0;
sp->subpid=0;
- shp->st.trapcom[0] = trap;
+ shp->st.trapcom[0] = (comsub==2?NULL:trap);
shp->savesig = 0;
}
}
@@ -743,7 +743,6 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
fchdir(shp->pwdfd);
}
shp->subshare = sp->subshare;
- shp->comsub = sp->comsub;
shp->subdup = sp->subdup;
#if SHOPT_COSHELL
shp->coshell = sp->coshell;
@@ -773,7 +772,12 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
if(nsig>0)
kill(getpid(),nsig);
if(sp->subpid)
+ {
job_wait(sp->subpid);
+ if(comsub>1)
+ iounpipe(shp);
+ }
+ shp->comsub = sp->comsub;
if(comsub && iop && sp->pipefd<0)
sfseek(iop,(off_t)0,SEEK_SET);
if(shp->trapnote)
diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.macro ksh-20120801/src/cmd/ksh93/sh/xec.c
--- ksh-20120801/src/cmd/ksh93/sh/xec.c.macro 2013-07-04 16:14:05.800595891 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2013-07-04 16:14:05.810595975 +0200
@@ -102,11 +102,11 @@ struct funenv
* temp file.
*/
static int subpipe[3],subdup,tsetio,usepipe;
-static void iounpipe(Shell_t*);
+void iounpipe(Shell_t*);
-static int iousepipe(Shell_t *shp)
+int iousepipe(Shell_t *shp)
{
- int i;
+ int fd=sffileno(sfstdout),i,err=errno;
if(usepipe)
{
usepipe++;
@@ -115,13 +115,18 @@ static int iousepipe(Shell_t *shp)
if(sh_rpipe(subpipe) < 0)
return(0);
usepipe++;
- fcntl(subpipe[0],F_SETFD,FD_CLOEXEC);
- subpipe[2] = sh_fcntl(1,F_DUPFD,10);
- fcntl(subpipe[2],F_SETFD,FD_CLOEXEC);
+ if(shp->comsub!=1)
+ {
+ subpipe[2] = sh_fcntl(subpipe[1],F_DUPFD,10);
+ sh_close(subpipe[1]);
+ return(1);
+ }
+ subpipe[2] = sh_fcntl(fd,F_dupfd_cloexec,10);
shp->fdstatus[subpipe[2]] = shp->fdstatus[1];
- close(1);
- fcntl(subpipe[1],F_DUPFD,1);
- shp->fdstatus[1] = shp->fdstatus[subpipe[1]];
+ while(close(fd)<0 && errno==EINTR)
+ errno = err;
+ fcntl(subpipe[1],F_DUPFD,fd);
+ shp->fdstatus[1] = shp->fdstatus[subpipe[1]]&~IOCLEX;
sh_close(subpipe[1]);
if(subdup=shp->subdup) for(i=0; i < 10; i++)
{
@@ -135,14 +140,23 @@ static int iousepipe(Shell_t *shp)
return(1);
}
-static void iounpipe(Shell_t *shp)
+void iounpipe(Shell_t *shp)
{
- int n;
+ int fd=sffileno(sfstdout),n,err=errno;
char buff[SF_BUFSIZE];
- close(1);
- fcntl(subpipe[2], F_DUPFD, 1);
- shp->fdstatus[1] = shp->fdstatus[subpipe[2]];
+ if(!usepipe)
+ return;
--usepipe;
+ if(shp->comsub>1)
+ {
+ sh_close(subpipe[2]);
+ while(read(subpipe[0],buff,sizeof(buff))>0);
+ goto done;
+ }
+ while(close(fd)<0 && errno==EINTR)
+ errno = err;
+ fcntl(subpipe[2], F_DUPFD, fd);
+ shp->fdstatus[1] = shp->fdstatus[subpipe[2]];
if(subdup) for(n=0; n < 10; n++)
{
if(subdup&(1<<n))
@@ -174,6 +188,7 @@ static void iounpipe(Shell_t *shp)
else if(errno!=EINTR)
break;
}
+done:
sh_close(subpipe[0]);
subpipe[0] = -1;
tsetio = 0;
@@ -725,7 +740,7 @@ static void unset_instance(Namval_t *nq,
}
#if SHOPT_COSHELL
-uintmax_t coused;
+static uintmax_t coused;
/*
* print out function definition
*/
@@ -1619,10 +1634,14 @@ int sh_exec(register const Shnode_t *t,
if(shp->subshell)
{
sh_subtmpfile(shp);
- if(shp->comsub==1 && !(shp->fdstatus[1]&IONOSEEK))
- unpipe=iousepipe(shp);
if((type&(FAMP|TFORK))==(FAMP|TFORK))
- sh_subfork();
+ {
+ if(shp->comsub && !(shp->fdstatus[1]&IONOSEEK))
+ {
+ unpipe = iousepipe(shp);
+ sh_subfork();
+ }
+ }
}
no_fork = !ntflag && !(type&(FAMP|FPOU)) && !shp->subshell &&
!(shp->st.trapcom[SIGINT] && *shp->st.trapcom[SIGINT]) &&
@@ -3495,8 +3514,7 @@ static void sh_funct(Shell_t *shp,Namval
struct funenv fun;
char *fname = nv_getval(SH_FUNNAMENOD);
struct Level *lp =(struct Level*)(SH_LEVELNOD->nvfun);
- int level, pipepid=shp->pipepid, comsub=shp->comsub;
- shp->comsub = 0;
+ int level, pipepid=shp->pipepid;
shp->pipepid = 0;
sh_stats(STAT_FUNCT);
if(!lp->hdr.disc)
@@ -3539,7 +3557,6 @@ static void sh_funct(Shell_t *shp,Namval
lp->maxlevel = level;
SH_LEVELNOD->nvalue.s = lp->maxlevel;
shp->last_root = nv_dict(DOTSHNOD);
- shp->comsub = comsub;
#if 0
nv_putval(SH_FUNNAMENOD,shp->st.funname,NV_NOFREE);
#else

View File

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

View File

@ -0,0 +1,37 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/array.c.memlik ksh-20120801/src/cmd/ksh93/sh/array.c
--- ksh-20120801/src/cmd/ksh93/sh/array.c.memlik 2012-06-07 00:00:42.000000000 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/array.c 2013-06-11 16:52:47.557123973 +0200
@@ -1701,7 +1701,11 @@ void *nv_associative(register Namval_t *
ap->header.scope = 0;
}
else
- dtclose(ap->header.table);
+ {
+ if((ap->header.nelem&ARRAY_MASK)==0 && (ap->cur=nv_search("0",ap->header.table,0)))
+ nv_associative(np,(char*)0,NV_ADELETE);
+ dtclose(ap->header.table);
+ }
return((void*)ap);
case NV_ANEXT:
if(!ap->pos)
diff -up ksh-20120801/src/cmd/ksh93/sh/name.c.memlik ksh-20120801/src/cmd/ksh93/sh/name.c
--- ksh-20120801/src/cmd/ksh93/sh/name.c.memlik 2012-07-23 18:21:57.000000000 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/name.c 2013-06-11 16:19:41.036648218 +0200
@@ -2465,6 +2465,8 @@ static void table_unset(Shell_t *shp, re
}
}
npnext = (Namval_t*)dtnext(root,np);
+ if(nv_arrayptr(np))
+ nv_putsub(np,NIL(char*),ARRAY_SCAN);
_nv_unset(np,flags);
nv_delete(np,root,0);
}
@@ -3326,7 +3328,7 @@ int nv_rename(register Namval_t *np, int
shp->last_root = last_root;
if(flags&NV_MOVE)
{
- if(arraynp && !nv_isattr(np,NV_MINIMAL) && (mp=(Namval_t*)np->nvenv) && (ap=nv_arrayptr(mp)))
+ if(arraynp && !nv_isattr(np,NV_MINIMAL) && (mp=(Namval_t*)np->nvenv) && (ap=nv_arrayptr(mp)) && !ap->fun)
ap->nelem++;
}
if((nv_arrayptr(nr) && !arraynr) || nv_isvtree(nr))

View File

@ -0,0 +1,76 @@
diff -up ksh-20120801/src/cmd/ksh93/include/name.h.memlik3 ksh-20120801/src/cmd/ksh93/include/name.h
--- ksh-20120801/src/cmd/ksh93/include/name.h.memlik3 2012-05-10 18:33:41.000000000 +0200
+++ ksh-20120801/src/cmd/ksh93/include/name.h 2014-01-22 14:14:32.774483776 +0100
@@ -215,7 +215,7 @@ extern Namval_t *nv_mount(Namval_t*, co
extern Namval_t *nv_arraychild(Namval_t*, Namval_t*, int);
extern int nv_compare(Dt_t*, Void_t*, Void_t*, Dtdisc_t*);
extern void nv_outnode(Namval_t*,Sfio_t*, int, int);
-extern int nv_subsaved(Namval_t*);
+extern int nv_subsaved(Namval_t*,int);
extern void nv_typename(Namval_t*, Sfio_t*);
extern void nv_newtype(Namval_t*);
extern int nv_istable(Namval_t*);
diff -up ksh-20120801/src/cmd/ksh93/sh/name.c.memlik3 ksh-20120801/src/cmd/ksh93/sh/name.c
--- ksh-20120801/src/cmd/ksh93/sh/name.c.memlik3 2014-01-22 14:14:32.751483987 +0100
+++ ksh-20120801/src/cmd/ksh93/sh/name.c 2014-01-22 14:14:32.775483767 +0100
@@ -1297,7 +1297,7 @@ void nv_delete(Namval_t* np, Dt_t *root,
{
if(dtdelete(root,np))
{
- if(!(flags&NV_NOFREE) && ((flags&NV_FUNCTION) || !nv_subsaved(np)))
+ if(!(flags&NV_NOFREE) && ((flags&NV_FUNCTION) || !nv_subsaved(np,flags&NV_TABLE)))
free((void*)np);
}
#if 0
@@ -2461,14 +2461,14 @@ static void table_unset(Shell_t *shp, re
{
_nv_unset(nq,flags);
npnext = (Namval_t*)dtnext(root,nq);
- nv_delete(nq,root,0);
+ nv_delete(nq,root,NV_TABLE);
}
}
npnext = (Namval_t*)dtnext(root,np);
if(nv_arrayptr(np))
nv_putsub(np,NIL(char*),ARRAY_SCAN);
_nv_unset(np,flags);
- nv_delete(np,root,0);
+ nv_delete(np,root,NV_TABLE);
}
}
diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.memlik3 ksh-20120801/src/cmd/ksh93/sh/subshell.c
--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.memlik3 2014-01-22 14:14:32.768483831 +0100
+++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2014-01-22 14:20:50.810236676 +0100
@@ -218,16 +218,28 @@ void sh_subfork(void)
}
}
-int nv_subsaved(register Namval_t *np)
+int nv_subsaved(register Namval_t *np,int table)
{
register struct subshell *sp;
- register struct Link *lp;
+ register struct Link *lp, *lpprev;
for(sp = (struct subshell*)subshell_data; sp; sp=sp->prev)
{
- for(lp=sp->svar; lp; lp = lp->next)
+ lpprev = 0;
+ for(lp=sp->svar; lp; lpprev=lp, lp=lp->next)
{
if(lp->node==np)
+ {
+ if(table&NV_TABLE)
+ {
+ if(lpprev)
+ lpprev->next = lp->next;
+ else
+ sp->svar = lp->next;
+ free((void*)np);
+ free((void*)lp);
+ }
return(1);
+ }
}
}
return(0);

View File

@ -0,0 +1,34 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/lex.c.mlikfiks ksh-20120801/src/cmd/ksh93/sh/lex.c
--- ksh-20120801/src/cmd/ksh93/sh/lex.c.mlikfiks 2013-07-22 12:45:30.923170264 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/lex.c 2013-07-22 12:46:25.235556905 +0200
@@ -2465,7 +2465,7 @@ static int alias_exceptf(Sfio_t *iop,int
if(dp!=handle)
sfdisc(iop,dp);
}
- else if(type==SF_FINAL)
+ else if(type==SF_DPOP || type==SF_FINAL)
free((void*)ap);
goto done;
}
diff -up ksh-20120801/src/cmd/ksh93/sh/path.c.mlikfiks ksh-20120801/src/cmd/ksh93/sh/path.c
--- ksh-20120801/src/cmd/ksh93/sh/path.c.mlikfiks 2013-07-22 12:47:23.149990016 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/path.c 2013-07-22 12:48:33.363283877 +0200
@@ -613,6 +613,7 @@ static void funload(Shell_t *shp,int fno
}
while((rp=dtnext(shp->fpathdict,rp)) && strcmp(pname,rp->fname)==0);
sh_close(fno);
+ free((void*)pname);
return;
}
sh_onstate(SH_NOLOG);
diff -up ksh-20120801/src/cmd/ksh93/sh/macro.c.aliasfix ksh-20120801/src/cmd/ksh93/sh/macro.c
--- ksh-20120801/src/cmd/ksh93/sh/macro.c.aliasfix 2013-07-29 15:03:45.841680475 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/macro.c 2013-07-29 15:04:23.871336821 +0200
@@ -2085,6 +2085,7 @@ static void comsubst(Mac_t *mp,register
}
sfputc(stkp,c);
}
+ sfputc(stkp,' ');
c = stktell(stkp);
str=stkfreeze(stkp,1);
/* disable verbose and don't save in history file */

View File

@ -0,0 +1,12 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.mtty ksh-20120801/src/cmd/ksh93/sh/xec.c
--- ksh-20120801/src/cmd/ksh93/sh/xec.c.mtty 2014-01-22 16:52:06.441608750 +0100
+++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2014-01-22 16:52:06.485608361 +0100
@@ -3163,7 +3169,7 @@ pid_t _sh_fork(Shell_t *shp,register pid
* completed. Make parent the job group id.
*/
if(postid==0)
- job.curpgid = parent;
+ job.curpgid = job.jobcontrol?parent:getpid();
if(job.jobcontrol || (flags&FAMP))
{
if(setpgid(parent,job.curpgid)<0 && errno==EPERM)

View File

@ -0,0 +1,11 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.nohupfork ksh-20120801/src/cmd/ksh93/sh/xec.c
--- ksh-20120801/src/cmd/ksh93/sh/xec.c.nohupfork 2015-08-27 14:25:38.925378019 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2015-08-27 14:30:42.267058087 +0200
@@ -2067,6 +2067,7 @@ int sh_exec(register const Shnode_t *t,
{
sh_exec(t->par.partre,flags);
shp->st.trapcom[0]=0;
+ sh_offoption(SH_INTERACTIVE);
sh_done(shp,0);
}
}

View File

@ -0,0 +1,11 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/init.c.nomulti ksh-20120801/src/cmd/ksh93/sh/init.c
--- ksh-20120801/src/cmd/ksh93/sh/init.c.nomulti 2013-10-08 20:46:46.202471042 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/init.c 2013-10-08 20:46:57.912331483 +0200
@@ -1446,7 +1446,6 @@ Shell_t *sh_init(register int argc,regis
#endif /* SHOPT_TIMEOUT */
/* initialize jobs table */
job_clear();
- sh_onoption(SH_MULTILINE);
if(argc>0)
{
/* check for restricted shell */

View File

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

View File

@ -0,0 +1,95 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/init.c.fixset ksh-20120801/src/cmd/ksh93/sh/init.c
--- ksh-20120801/src/cmd/ksh93/sh/init.c.fixset 2014-11-03 15:45:36.510997271 +0100
+++ ksh-20120801/src/cmd/ksh93/sh/init.c 2014-11-03 16:20:44.398917280 +0100
@@ -2003,8 +2003,91 @@ static Dt_t *inittree(Shell_t *shp,const
* skip over items that are not name-value pairs
*/
+
static void env_init(Shell_t *shp)
{
+ register char *cp;
+ register Namval_t *np;
+ register char **ep=environ;
+ register char *next=0;
+#ifdef _ENV_H
+ shp->env = env_open(environ,3);
+ env_delete(shp->env,"_");
+#endif
+ if(ep)
+ {
+ while(cp= *ep++)
+ {
+ if(*cp=='A' && cp[1]=='_' && cp[2]=='_' && cp[3]=='z' && cp[4]=='=')
+ next = cp+4;
+ else if(np=nv_open(cp,shp->var_tree,(NV_EXPORT|NV_IDENT|NV_ASSIGN|NV_NOFAIL)))
+ {
+ nv_onattr(np,NV_IMPORT);
+ np->nvenv = cp;
+ nv_close(np);
+ }
+ else /* swap with front */
+ {
+ ep[-1] = environ[shp->nenv];
+ environ[shp->nenv++] = cp;
+ }
+ }
+ while(cp=next)
+ {
+ if(next = strchr(++cp,'='))
+ *next = 0;
+ np = nv_search(cp+2,shp->var_tree,NV_ADD);
+ if(np!=SHLVL && nv_isattr(np,NV_IMPORT|NV_EXPORT))
+ {
+ int flag = *(unsigned char*)cp-' ';
+ int size = *(unsigned char*)(cp+1)-' ';
+ if((flag&NV_INTEGER) && size==0)
+ {
+ /* check for floating*/
+ char *ep,*val = nv_getval(np);
+ strtol(val,&ep,10);
+ if(*ep=='.' || *ep=='e' || *ep=='E')
+ {
+ char *lp;
+ flag |= NV_DOUBLE;
+ if(*ep=='.')
+ {
+ strtol(ep+1,&lp,10);
+ if(*lp)
+ ep = lp;
+ }
+ if(*ep && *ep!='.')
+ {
+ flag |= NV_EXPNOTE;
+ size = ep-val;
+ }
+ else
+ size = strlen(ep);
+ size--;
+ }
+ }
+ nv_newattr(np,flag|NV_IMPORT|NV_EXPORT,size);
+ }
+ else
+ cp += 2;
+ }
+ }
+#ifdef _ENV_H
+ env_delete(shp->env,e_envmarker);
+#endif
+ if(nv_isnull(PWDNOD) || nv_isattr(PWDNOD,NV_TAGGED))
+ {
+ nv_offattr(PWDNOD,NV_TAGGED);
+ path_pwd(shp,0);
+ }
+ if((cp = nv_getval(SHELLNOD)) && (sh_type(cp)&SH_TYPE_RESTRICTED))
+ sh_onoption(SH_RESTRICTED); /* restricted shell */
+ return;
+}
+
+
+static void env_init_backup(Shell_t *shp)
+{
register char *cp;
register Namval_t *np,*mp;
register char **ep=environ;

View File

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

View File

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

View File

@ -0,0 +1,14 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.retfix ksh-20120801/src/cmd/ksh93/sh/subshell.c
--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.retfix 2014-10-01 17:34:47.720532950 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2014-10-01 17:35:25.850350378 +0200
@@ -655,7 +655,10 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
job.hack1_waitall=0;
if(comsub!=1 && shp->spid)
{
+ int c = shp->exitval;
job_wait(shp->spid);
+ shp->exitval = c;
+ exitset();
if(shp->pipepid==shp->spid)
shp->spid = 0;
shp->pipepid = 0;

View File

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

View File

@ -0,0 +1,12 @@
diff -up ksh-20120801/src/lib/libast/sfio/sfcvt.c.rounditgood ksh-20120801/src/lib/libast/sfio/sfcvt.c
--- ksh-20120801/src/lib/libast/sfio/sfcvt.c.rounditgood 2014-02-27 16:45:54.630161032 +0100
+++ ksh-20120801/src/lib/libast/sfio/sfcvt.c 2014-02-27 16:45:54.658161205 +0100
@@ -491,7 +491,7 @@ int format; /* conversion format */
*decpt += 1;
if(!(format&SFFMT_EFORMAT))
{ /* add one more 0 for %f precision */
- ep[-1] = '0';
+ if(ep-sp>1) ep[-1] = '0';
ep += 1;
}
}

View File

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

View File

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

View File

@ -31,28 +31,23 @@ src/cmd/ksh93/edit/history.c: sh_histinit():
[*] https://man7.org/linux/man-pages/man3/ttyname.3.html
---
src/cmd/ksh93/edit/history.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
src/cmd/ksh93/edit/history.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/cmd/ksh93/edit/history.c b/src/cmd/ksh93/edit/history.c
index a7b084e5c16f..25832a59265b 100644
index de5e4a8..222d4bc 100644
--- a/src/cmd/ksh93/edit/history.c
+++ b/src/cmd/ksh93/edit/history.c
@@ -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)
@@ -395,7 +395,8 @@ retry:
if(fd>=0)
{
fcntl(fd,F_SETFD,FD_CLOEXEC);
- hp->tty = sh_strdup(isatty(2)?ttyname(2):"notty");
- hp->tty = strdup(ttyname(2));
+ const char* tty = ttyname(2);
+ hp->tty = sh_strdup(tty?tty:"notty");
hp->auditfp = sfnew(NULL,NULL,-1,fd,SF_WRITE);
+ hp->tty = strdup(tty?tty:"notty");
hp->auditfp = sfnew((Sfio_t*)0,NULL,-1,fd,SF_WRITE);
}
}
--
2.43.0

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,11 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/io.c.sufix ksh-20120801/src/cmd/ksh93/sh/io.c
--- ksh-20120801/src/cmd/ksh93/sh/io.c.sufix 2014-04-08 14:30:14.412343555 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/io.c 2014-04-08 14:31:18.403876587 +0200
@@ -2144,6 +2144,7 @@ static int io_prompt(Shell_t *shp,Sfio_t
}
#endif /* TIOCLBIC */
cp = sh_mactry(shp,nv_getval(sh_scoped(shp,PS1NOD)));
+ shp->exitval = 0;
for(;c= *cp;cp++)
{
if(c==HIST_CHAR)

View File

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

View File

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

View File

@ -0,0 +1,12 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/init.c.tpstl ksh-20120801/src/cmd/ksh93/sh/init.c
--- ksh-20120801/src/cmd/ksh93/sh/init.c.tpstl 2014-04-03 11:21:25.395547276 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/init.c 2014-04-03 11:26:03.908867208 +0200
@@ -332,7 +332,7 @@ static Namfun_t *clone_optindex(Namval_t
/* Trap for restricted variables FPATH, PATH, SHELL, ENV */
static void put_restricted(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
{
- Shell_t *shp = nv_shell(np);
+ Shell_t *shp = sh_getinterp();
int path_scoped = 0, fpath_scoped=0;
Pathcomp_t *pp;
char *name = nv_name(np);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,29 @@
diff -up ksh-20120801/src/cmd/ksh93/bltins/typeset.c.xufix ksh-20120801/src/cmd/ksh93/bltins/typeset.c
--- ksh-20120801/src/cmd/ksh93/bltins/typeset.c.xufix 2015-02-03 14:47:23.266022137 +0100
+++ ksh-20120801/src/cmd/ksh93/bltins/typeset.c 2015-02-03 14:47:23.308022046 +0100
@@ -93,6 +93,8 @@ int b_readonly(int argc,char *argv[],
memset((void*)&tdata,0,sizeof(tdata));
tdata.sh = context->shp;
tdata.aflag = '-';
+ /* do not change size */
+ tdata.argnum = -1;
while((flag = optget(argv,*command=='e'?sh_optexport:sh_optreadonly))) switch(flag)
{
case 'p':
diff -up ksh-20120801/src/cmd/ksh93/sh/name.c.xufix ksh-20120801/src/cmd/ksh93/sh/name.c
--- ksh-20120801/src/cmd/ksh93/sh/name.c.xufix 2015-02-03 14:47:23.281022105 +0100
+++ ksh-20120801/src/cmd/ksh93/sh/name.c 2015-02-03 14:52:08.768404194 +0100
@@ -3019,10 +3019,12 @@ void nv_newattr (register Namval_t *np,
nv_onattr(np,NV_EXPORT);
sh_envput(shp->env,np);
}
- if((n^newatts)==NV_EXPORT)
+ if((n^newatts)==NV_EXPORT && size==-1)
return;
}
oldsize = nv_size(np);
+ if (size == -1)
+ size = oldsize;
if((size==oldsize|| (n&NV_INTEGER)) && !trans && ((n^newatts)&~NV_NOCHANGE)==0)
{
if(size)

View File

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

View File

@ -0,0 +1,15 @@
diff -up ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.cdfix4 ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c
--- ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c.cdfix4 2014-08-26 15:24:57.276953822 +0200
+++ ksh-20120801/src/cmd/ksh93/bltins/cd_pwd.c 2014-08-26 15:25:34.738770361 +0200
@@ -143,9 +143,9 @@ int sh_diropenat(Shell_t *shp, int dir,
}
/* Move fd to a number > 10 and *register* the fd number with the shell */
- shfd = sh_fcntl(fd, F_dupfd_cloexec, 10);
+ shfd = fcntl(fd, F_dupfd_cloexec, 10);
savederrno=errno;
- sh_close(fd);
+ close(fd);
errno=savederrno;
return(shfd);
}

View File

@ -0,0 +1,58 @@
diff -up ksh-20120801/src/cmd/ksh93/include/defs.h.longer ksh-20120801/src/cmd/ksh93/include/defs.h
--- ksh-20120801/src/cmd/ksh93/include/defs.h.longer 2012-06-25 20:47:47.000000000 +0200
+++ ksh-20120801/src/cmd/ksh93/include/defs.h 2013-07-08 17:33:42.238534376 +0200
@@ -162,8 +162,8 @@ struct shared
Namval_t *prev_table; /* previous table used in nv_open */ \
Sfio_t *outpool; /* ouput stream pool */ \
long timeout; /* read timeout */ \
- short curenv; /* current subshell number */ \
- short jobenv; /* subshell number for jobs */ \
+ long curenv; /* current subshell number */ \
+ long jobenv; /* subshell number for jobs */ \
int infd; /* input file descriptor */ \
short nextprompt; /* next prompt is PS<nextprompt> */ \
short poolfiles; \
diff -up ksh-20120801/src/cmd/ksh93/include/jobs.h.longer ksh-20120801/src/cmd/ksh93/include/jobs.h
--- ksh-20120801/src/cmd/ksh93/include/jobs.h.longer 2011-12-19 13:36:37.000000000 +0100
+++ ksh-20120801/src/cmd/ksh93/include/jobs.h 2013-07-08 17:32:52.881124147 +0200
@@ -87,7 +87,7 @@ struct process
unsigned short p_exit; /* exit value or signal number */
unsigned short p_exitmin; /* minimum exit value for xargs */
unsigned short p_flag; /* flags - see below */
- int p_env; /* subshell environment number */
+ long p_env; /* subshell environment number */
#ifdef JOBS
off_t p_name; /* history file offset for command */
struct termios p_stty; /* terminal state for job */
diff -up ksh-20120801/src/cmd/ksh93/sh/jobs.c.longer ksh-20120801/src/cmd/ksh93/sh/jobs.c
diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.longer ksh-20120801/src/cmd/ksh93/sh/subshell.c
--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.longer 2013-07-08 17:32:52.874124090 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2013-07-08 17:32:52.882124156 +0200
@@ -98,7 +98,7 @@ static struct subshell
#endif /* SHOPT_COSHELL */
} *subshell_data;
-static int subenv;
+static long subenv;
/*
@@ -171,7 +171,8 @@ void sh_subfork(void)
{
register struct subshell *sp = subshell_data;
Shell_t *shp = sp->shp;
- int curenv = shp->curenv, comsub=shp->comsub;
+ long curenv = shp->curenv;
+ int comsub=shp->comsub;
pid_t pid;
char *trap = shp->st.trapcom[0];
if(trap)
@@ -461,7 +462,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
struct subshell sub_data;
register struct subshell *sp = &sub_data;
int jmpval,nsig=0,duped=0;
- int savecurenv = shp->curenv;
+ long savecurenv = shp->curenv;
int savejobpgid = job.curpgid;
int *saveexitval = job.exitval;
int16_t subshell;

View File

@ -0,0 +1,12 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/expand.c.fikspand ksh-20120801/src/cmd/ksh93/sh/expand.c
--- ksh-20120801/src/cmd/ksh93/sh/expand.c.fikspand 2010-11-24 05:46:30.000000000 +0100
+++ ksh-20120801/src/cmd/ksh93/sh/expand.c 2014-05-22 12:55:46.252717371 +0200
@@ -278,6 +278,8 @@ int path_generate(Shell_t *shp,struct ar
char comma, range=0;
int first, last, incr, count = 0;
char tmp[32], end[1];
+ if(!sh_isoption(SH_BRACEEXPAND))
+ return path_expand(shp,todo->argval,arghead);
todo->argchn.ap = 0;
again:
apin = ap = todo;

View File

@ -0,0 +1,37 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/xec.c.hokaido ksh-20120801/src/cmd/ksh93/sh/xec.c
--- ksh-20120801/src/cmd/ksh93/sh/xec.c.hokaido 2014-09-18 14:41:57.696756230 +0200
+++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2014-09-18 14:43:55.439205247 +0200
@@ -1633,12 +1633,20 @@ int sh_exec(register const Shnode_t *t,
#endif /* SHOPT_COSHELL */
if(shp->subshell)
{
+ int comsubsave = shp->comsub;
+ if(comsubsave==1)
+ shp->comsub = 2;
sh_subtmpfile(shp);
+ shp->comsub = comsubsave;
+ if(shp->comsub==1 && (!(shp->fdstatus[1]&IONOSEEK)))
+ unpipe = iousepipe(shp);
+
if((type&(FAMP|TFORK))==(FAMP|TFORK))
{
if(shp->comsub && !(shp->fdstatus[1]&IONOSEEK))
{
- unpipe = iousepipe(shp);
+ if (!unpipe)
+ unpipe = iousepipe(shp);
sh_subfork();
}
}
@@ -2107,7 +2115,11 @@ int sh_exec(register const Shnode_t *t,
job.curjobid = 0;
if(shp->subshell)
{
+ int comsubsave = shp->comsub;
+ if(comsubsave==1)
+ shp->comsub = 2;
sh_subtmpfile(shp);
+ shp->comsub = comsubsave;
if(shp->comsub==1 && !(shp->fdstatus[1]&IONOSEEK))
iousepipe(shp);
}

View File

@ -0,0 +1,11 @@
--- ksh-20120801/src/cmd/ksh93/sh/xec.c 2015-04-02 10:55:26.228017873 -0400
+++ ksh-20120801/src/cmd/ksh93/sh/xec.c 2015-04-02 10:56:04.099017700 -0400
@@ -1234,7 +1234,7 @@ int sh_exec(register const Shnode_t *t,
if((io||argn))
{
Shbltin_t *bp=0;
- static char *argv[1];
+ static char *argv[2];
int tflags = 1;
if(np && nv_isattr(np,BLT_DCL))
tflags |= 2;

View File

@ -0,0 +1,21 @@
diff -up ksh-20120801/src/cmd/ksh93/sh/main.c.orig ksh-20120801/src/cmd/ksh93/sh/main.c
--- ksh-20120801/src/cmd/ksh93/sh/main.c.orig 2015-04-29 16:49:11.502958000 -0300
+++ ksh-20120801/src/cmd/ksh93/sh/main.c 2015-05-08 18:19:55.688776922 -0300
@@ -423,7 +423,7 @@ static void exfile(register Shell_t *shp
sfsync(shp->outpool);
shp->st.execbrk = shp->st.breakcnt = 0;
/* check for return from profile or env file */
- if(sh_isstate(SH_PROFILE) && (jmpval==SH_JMPFUN || jmpval==SH_JMPEXIT))
+ if(sh_isstate(SH_PROFILE) && (jmpval==SH_JMPFUN || jmpval==SH_JMPEXIT || jmpval==SH_JMPERREXIT))
{
sh_setstate(states);
goto done;
@@ -598,7 +598,7 @@ done:
}
if(jmpval == SH_JMPSCRIPT)
siglongjmp(*shp->jmplist,jmpval);
- else if(jmpval == SH_JMPEXIT)
+ else if(jmpval == SH_JMPEXIT || jmpval == SH_JMPERREXIT)
sh_done(shp,0);
if(fno>0)
sh_close(fno);

View File

@ -0,0 +1,52 @@
diff -up ksh-20120801/src/cmd/ksh93/include/io.h.safefd ksh-20120801/src/cmd/ksh93/include/io.h
--- ksh-20120801/src/cmd/ksh93/include/io.h.safefd 2015-03-03 18:21:40.544732158 +0100
+++ ksh-20120801/src/cmd/ksh93/include/io.h 2015-03-03 18:22:16.284447849 +0100
@@ -78,6 +78,7 @@ extern void sh_iorestore(Shell_t*,int,i
extern Sfio_t *sh_iostream(Shell_t*,int);
extern int sh_redirect(Shell_t*,struct ionod*,int);
extern void sh_iosave(Shell_t *, int,int,char*);
+extern int safefdnumber(Shell_t* shp, int sfd);
extern int sh_iovalidfd(Shell_t*, int);
extern int sh_inuse(Shell_t*, int);
extern void sh_iounsave(Shell_t*);
diff -up ksh-20120801/src/cmd/ksh93/sh/io.c.safefd ksh-20120801/src/cmd/ksh93/sh/io.c
--- ksh-20120801/src/cmd/ksh93/sh/io.c.safefd 2015-03-03 18:21:40.511732421 +0100
+++ ksh-20120801/src/cmd/ksh93/sh/io.c 2015-03-03 18:21:40.544732158 +0100
@@ -1724,6 +1724,25 @@ void sh_iosave(Shell_t *shp, register in
}
}
+int safefdnumber(Shell_t* shp, int sfd)
+{
+ register int fd;
+
+ while(1)
+ {
+ for(fd=0; fd < shp->topfd; fd++)
+ {
+ if (filemap[fd].save_fd==sfd || filemap[fd].orig_fd==sfd || (fcntl(sfd, F_GETFD) != -1 || errno != EBADF))
+ {
+ sfd++;
+ continue;
+ }
+ }
+ break;
+ }
+ return sfd;
+}
+
/*
* close all saved file descriptors
*/
diff -up ksh-20120801/src/cmd/ksh93/sh/subshell.c.safefd ksh-20120801/src/cmd/ksh93/sh/subshell.c
--- ksh-20120801/src/cmd/ksh93/sh/subshell.c.safefd 2015-03-03 18:21:40.531732261 +0100
+++ ksh-20120801/src/cmd/ksh93/sh/subshell.c 2015-03-03 18:21:40.544732158 +0100
@@ -673,7 +673,7 @@ Sfio_t *sh_subshell(Shell_t *shp,Shnode_
}
if(iop && sffileno(iop)==1)
{
- int fd=sfsetfd(iop,3);
+ int fd=sfsetfd(iop,safefdnumber(shp,3));
if(fd<0)
{
shp->toomany = 1;

View File

@ -1,45 +1,273 @@
%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
Epoch: 3
Version: 1.0.6
Release: 4%{?dist}
Source0: https://github.com/ksh93/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz
Source1: kshcomp.conf
Source2: kshrc.rhs
Source3: dotkshrc
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
# 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
# expected results of test suite
Source5: expectedresults.log
#https://github.com/ksh93/ksh/commit/2075b2b96208ac8b989ca316dcdd674c3f488e2b
Patch3: %{name}-1.0.7-history-trim.patch
# don't use not wanted/needed builtins - Fedora/RHEL specific
Patch1: ksh-20070328-builtins.patch
# fix regression test suite to be usable during packagebuild - Fedora/RHEL specific
Patch2: ksh-20100826-fixregr.patch
# fedora/rhel specific, rhbz#619692
Patch6: ksh-20080202-manfix.patch
# rhbz#702008
Patch17: ksh-20100202-pathvar.patch
# rhbz#924440
Patch18: ksh-20100621-fdstatus.patch
# fixes for regressions found in ksh-20120801 rebase
Patch19: ksh-20120801-rmdirfix.patch
Patch20: ksh-20120801-cdfix.patch
Patch21: ksh-20120801-cdfix2.patch
Patch22: ksh-20120801-tabfix.patch
Patch23: ksh-20130214-fixkill.patch
# for ksh <= 2013-05-31, rhbz#960034
Patch24: ksh-20120801-kshmfix.patch
# for ksh <= 2016-06-28, rhbz#921455
Patch25: ksh-20120801-memlik.patch
# for ksh <= 2013-03-20, rhbz#922851
Patch26: ksh-20120801-forkbomb.patch
# for ksh <= 2013-04-19, rhbz#913110
Patch27: ksh-20120801-macro.patch
# not completely upstream yet, rhbz#858263
Patch29: ksh-20130628-longer.patch
# for ksh <= 2013-07-19, rhbz#982142
Patch30: ksh-20120801-mlikfiks.patch
# not yet upstream, related to 2012-08-01 rebase
Patch31: ksh-20120801-covsfix.patch
# rhbz#1007816
Patch32: ksh-20100621-manfix3.patch
# rhbz#1016611
Patch33: ksh-20120801-nomulti.patch
# for ksh <= 2014-01-14, rhbz#
Patch34: ksh-20120801-mtty.patch
# from upstream, rbzh#1048272
Patch35: ksh-20120801-fd2lost.patch
# sent upstream 2014-01, rhbz#1047507
Patch36: ksh-20120801-argvfix.patch
# for ksh <= 2014-01-14, rhbz#1048995
Patch37: ksh-20120801-memlik3.patch
# for ksh <= 2013-04-09, rhbz#960371
Patch38: ksh-20120801-lexfix.patch
# not yet upstream, for ksh <= 2014-02-26, rhbz#1070328
Patch39: ksh-20120801-filecomsubst.patch
# for ksh <= 2014-06-25, rhbz#825520,rhbz#1084406
Patch40: ksh-20120801-crash.patch
# for ksh < 2013-03-19, rhbz#1085385
Patch41: ksh-20120801-sufix.patch
# sent upstream, rhbz#1099935
Patch42: ksh-20140301-fikspand.patch
# for ksh < 2014-04-15, rhbz#1070871
Patch43: ksh-20120801-roundit.patch
# for ksh < 2014-04-15, rhbz#1111120
Patch44: ksh-20120801-heresub.patch
# not included upstream yet, rhbz#1077090
Patch45: ksh-20140415-hokaido.patch
# for ksh < 2012-10-04, rhbz#1121960
Patch46: ksh-20120801-tpstl.patch
# not upstream yet, rhbz#1100215
Patch48: ksh-20120801-fununset.patch
# for ksh < 2014-06-25, rhbz#1109893
Patch49: ksh-20120801-cdfix3.patch
# sent upstream, rhbz#1116506
Patch50: ksh-20120801-locking.patch
# for ksh <= 2013-06-13, rhbz#1133585
Patch51: ksh-20130613-cdfix4.patch
Patch52: ksh-20120801-retfix.patch
# sent upstream, for ksh <= 2014-09-30
Patch53: ksh-20120801-cdfork.patch
# not upstream yet, for ksh <= 2015-04-03, rhbz#1200534
Patch54: ksh-20140801-arraylen.patch
# sent upstream, for ksh <= 2014-09-29, rhbz#1212993
Patch55: ksh-20140801-diskfull.patch
# not upstream yet, rhbz#1192026
Patch56: ksh-20120801-xufix.patch
# sent upstream, for ksh <= 2014-12-18, rhbz#1192119
Patch58: ksh-20120801-alarmifs.patch
# not yet upstream, rhbz#1202439
Patch59: ksh-20140929-safefd.patch
# workaround, for ksh < 2013-05-24, rhbz#1211540
Patch60: ksh-20120801-trapcom.patch
# not yet upstream, rhbz#1217237
Patch64: ksh-20120801-nohupfork.patch
# from upstream, for ksh <= 20130409, rhbz#1241014
Patch65: ksh-20120801-parserfix.patch
# not upstream yet, rhbz#1211538
Patch66: ksh-20120801-oldenvinit.patch
# from upsteam, for ksh < 2012-10-04, rhbz#1193557
Patch67: ksh-20120801-emptyarrayinit.patch
# not upstream yet, rhbz#1371630
Patch68: ksh-20120801-typeset.patch
# not upstream yet, rhbz#1321443
Patch69: ksh-20120801-dotdoublefree.patch
# not upstream yet, rhbz#1405784
Patch70: ksh-20120801-subshell-leak.patch
# rhbz#1189297
Patch71: ksh-20120801-assoc-unset-leak.patch
# rhbz#1222025
Patch72: ksh-20120801-unset-param.patch
# rhbz#1269088
Patch73: ksh-20120801-badgcc.patch
# rhbz#1299484
Patch74: ksh-20120801-mb-after-argvar.patch
Patch75: ksh-20120801-F_dupfd_cloexec.patch
# rhbz#1441142
Patch76: ksh-20120801-kia.patch
# rhbz#1417886
Patch77: ksh-20120801-iso8859.patch
# rhbz#1451057
Patch78: ksh-20120801-syntax-error.patch
# rhbz#1477082
Patch79: ksh-20120801-glibc-build-fix.patch
# rhbz#1459000
Patch80: ksh-20120801-jobwait-sigstop.patch
# rhbz#1462347
Patch81: ksh-20120801-subshell-jobwait.patch
# rhbz#1471874
Patch82: ksh-20120801-posix-exit.patch
# rhbz#1464409
Patch83: ksh-20120801-sh_iovalidfd.patch
# rhbz#1537053
Patch84: ksh-20120801-validate-fd.patch
# There were couple of places where CCFLAGS variable was not passed while
# compiling binaries. This patch fixes it. Loosely related to rhbz#1548549.
Patch85: ksh-20120801-ccflags.patch
Patch86: ksh-20120801-nv_open-memcmp.patch
Patch87: ksh-20120801-covsfix2.patch
# rhbz#1624125
Patch88: ksh-20120801-annocheck.patch
# rhbz#1790547
Patch89: ksh-20120801-cve-2019-14868.patch
# rhbz#1857847
Patch90: ksh-20120801-jobcontrol.patch
# rhbz#2060600
Patch91: ksh-20120801-signal-bubbling.patch
# rhbz#2116372
# upstream commit: https://github.com/ksh93/ksh/commit/4604df9ada906e0a6537157a63b6ce7c0509f34d
Patch92: ksh-20120801-stack-robustness.patch
# rhbz#2116372
# upstream commit: https://github.com/ksh93/ksh/commit/56805b25af24f454cdd477609bcddc984628bc01
Patch93: ksh-20120801-stack-robustness-2.patch
# rhbz#2013909
# upstream commit: https://github.com/ksh93/ksh/commit/6f3b23e6f4d59590a51bfbcc66dc60082728b71d
Patch94: ksh-20120801-segfault-long-command.patch
# rhbz#1948588
# upstream commit: https://github.com/ksh93/ksh/commit/74b4162178c8a2347491b9fd3a22d8e6e1b7e831
Patch95: ksh-20120801-set+r-fix.patch
# RHEL-11982
# upstream commit: https://github.com/ksh93/ksh/commit/9eb8532ccacf1cfdb7ba18f51eba68776852ef7c.patch
Patch4: ksh-1.0.7-segfault-strdup.patch
Patch96: ksh-20120801-segfault-strdup.patch
#upstream commit: https://github.com/ksh93/ksh/commit/428c0917f3043358c9b54cc137a5037d69b01ed4
Patch5: ksh-1.0.9-trap-return-status.patch
# RHEL-12011
# upstream commit: https://github.com/ksh93/ksh/commit/035a4cb3f453271b7ae63bcb53a7963b8dbe4c41
Patch97: ksh-20120801-segfault-cd-paths.patch
# RHEL-5684
# upstream commit: https://github.com/ksh93/ksh/commit/f9d28935bb93fe7336ba8c5eab4231050de2e11e
Patch98: ksh-20120801-xtrace-utf8-quoting.patch
# RHEL-5685
# upstream commit: https://github.com/ksh93/ksh/commit/2075b2b96208ac8b989ca316dcdd674c3f488e2b
Patch99: %{name}-1.0.7-history-trim.patch
# RHEL-11650
# upstream commit: https://github.com/ksh93/ksh/commit/70f6d758c0f2fda90bc3d49331397ffd62dca3af
# upstream commit: https://github.com/ksh93/ksh/commit/91a7c2e3e9feb8ac1391146ebcda9e6adfcd3cfb
Patch100: ksh-20120801-subshell-interrupt-segv.patch
Conflicts: pdksh
Requires: coreutils, diffutils
BuildRequires: gcc
Requires: coreutils, diffutils, chkconfig
BuildRequires: bison
# regression test suite uses 'ps' from procps
BuildRequires: procps
Requires(post): grep, coreutils, systemd
Requires(post): grep, coreutils, systemd-units, chkconfig
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
@ -48,20 +276,34 @@ KornShell is a shell programming language, which is upward compatible
with "sh" (the Bourne Shell).
%prep
%autosetup -p1
%autosetup -N -c
%autosetup -N -T -D -a 1
%autopatch -p1
#/dev/fd test does not work because of mock
sed -i 's|ls /dev/fd|ls /proc/self/fd|' src/cmd/ksh93/features/options
# sh/main.c was not using CCFLAGS
sed -i '/-c sh\/main.c/s|${mam_cc_FLAGS} |${mam_cc_FLAGS} ${CCFLAGS} |p' src/cmd/ksh93/Mamfile
# disable register for debugging
sed -i 1i"#define register" src/lib/libast/include/ast.h
%build
# rhbz#2226653: -D_std_malloc (disable vmalloc and force use of the operating system's malloc)
XTRAFLAGS=""
for f in -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
for f in -D_std_malloc -Wno-unknown-pragmas -Wno-missing-braces -Wno-unused-result -Wno-return-type -Wno-int-to-pointer-cast -Wno-parentheses -Wno-unused -Wno-unused-but-set-variable -Wno-cpp -P
do
$CC $f -E - </dev/null >/dev/null 2>&1 && XTRAFLAGS="$XTRAFLAGS $f"
gcc $f -E - </dev/null >/dev/null 2>&1 && XTRAFLAGS="$XTRAFLAGS $f"
done
export CCFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing $XTRAFLAGS"
export LDFLAGS="$RPM_LD_FLAGS"
./bin/package make
./bin/package
./bin/package make mamake ||:
./bin/package make mamake ||:
export CCFLAGS="$RPM_OPT_FLAGS $RPM_LD_FLAGS -fno-strict-aliasing $XTRAFLAGS"
export CC=gcc
./bin/package make -S
#cp lib/package/LICENSES/epl LICENSE
%install
mkdir -p %{buildroot}{/bin,%{_bindir},%{_mandir}/man1}
@ -69,18 +311,41 @@ 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 %{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
install -p -m 644 %{SOURCE4} %{buildroot}%{_sysconfdir}/skel/.kshrc
install -p -m 644 %{SOURCE3} %{buildroot}%{_sysconfdir}/kshrc
install -p -D -m 644 %{SOURCE2} %{buildroot}%{_sysconfdir}/binfmt.d/kshcomp.conf
ln -s %{_bindir}/ksh93 %{buildroot}/%{_bindir}/rksh
touch %{buildroot}%{_bindir}/ksh
touch %{buildroot}%{_mandir}/man1/ksh.1.gz
touch %{buildroot}%{_bindir}/rksh
touch %{buildroot}%{_mandir}/man1/rksh.1.gz
%check
./bin/shtests --compile
[ -f ./skipcheck -o -f ./../skipcheck ] && exit 0 ||:
%if 0%{?rhel} > 6
%ifarch s390
exit 0
%endif
%endif
export SHELL=$(ls $(pwd)/arch/*/bin/ksh)
cd src/cmd/ksh93/tests/
ulimit -c unlimited
if [ ! -e /dev/fd ]
then
echo "ERROR: /dev/fd does not exist, regression tests skipped"
exit 0
fi
$SHELL ./shtests 2>&1 | tee testresults.log
ls core.* 2>/dev/null ||:
exit 0
sed -e '/begins at/d' -e '/ 0 error/d' -e 's/at [^\[]*\[/\[/' testresults.log -e '/tests skipped/d' >filteredresults.log
if ! cmp filteredresults.log %{SOURCE5} >/dev/null || ls core.*
then
echo "Regression tests failed"
diff -Naurp %{SOURCE5} filteredresults.log
exit -1
fi
%post
for s in /bin/ksh /bin/rksh /usr/bin/ksh /usr/bin/rksh
@ -96,10 +361,6 @@ 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
@ -111,6 +372,7 @@ 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
@ -137,112 +399,91 @@ fi
%files
%doc src/cmd/ksh93/COMPATIBILITY src/cmd/ksh93/RELEASE src/cmd/ksh93/TYPES
%license LICENSE.md
# LICENSE file is missing, temporarily?
%{_bindir}/ksh93
%ghost %{_bindir}/ksh
%ghost %{_bindir}/rksh
%{_bindir}/rksh
%{_bindir}/shcomp
%{_mandir}/man1/*
%{_mandir}/man1/ksh93.1.gz
%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
* Tue Oct 01 2024 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-4
- Fix bad default 'return' status in traps
Resolves: RHEL-62228
* Fri Feb 09 2024 Vincent Mihalkovic <vmihalko@redhat.com> - 20120801-267
- Re-fix segfault in strdup
Resolves: RHEL-11982
* Sat Feb 10 2024 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-3
* Thu Jan 25 2024 Lukáš Zaoral <lzaoral@redhat.com> - 20120801-266
- fix crashes when interrupting subshells (RHEL-11650)
* Wed Jan 03 2024 Vincent Mihalkovic <vmihalko@redhat.com> - 20120801-265
- Fix crash on failure to trim ~/.sh_history (RHEL-5685)
* Wed Nov 22 2023 Vincent Mihalkovic <vmihalko@redhat.com> - 20120801-264
- Remove broken monitor patch
* Thu Nov 09 2023 Lukáš Zaoral <lzaoral@redhat.com> - 20120801-263
- fix UTF-8 quoting in xtrace
Resolves: RHEL-5684
* Wed Nov 08 2023 Lukáš Zaoral <lzaoral@redhat.com> - 20120801-262
- fix segfault in subshell if $PATH contains a .paths directory
Resolves: RHEL-12011
* Tue Oct 31 2023 Lukáš Zaoral <lzaoral@redhat.com> - 20120801-261
- Fix segfault in strdup
Resolves: RHEL-25019
Resolves: RHEL-11982
* Wed Jan 03 2024 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.6-2
- Fix crash on failure to trim ~/.sh_history (#20345)
* Mon Sep 18 2023 Lukáš Zaoral <lzaoral@redhat.com> - 20120801-260
- Fix set +r so that it cannot unset the restricted option
Resolves: #1948588
* 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
* Fri Aug 25 2023 Vincent Mihalkovic <vmihalko@redhat.com> - 20120801-259
- Fix crash on trying a very long command
Fix license tag
Resolves: #2013909
* Tue Jun 27 2023 Vincent Mihalkovic <vmihalko@redhat.com> - 3:1.0.0~beta.1-3
- fix segfault when PWD is unset
Resolves: #2123066
* Wed Jul 26 2023 Vincent Mihalkovic <vmihalko@redhat.com> - 20120801-258
- disable vmalloc and force use of the operating system's malloc
Resolves: #2226653
* Mon Aug 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
* Mon Aug 08 2022 Vincent Mihalkovic <vmihalko@redhat.com> - 20120801-257
- Stack robustness fixes (two patches)
Resolves: #2116372
* 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
* Thu Jul 21 2022 Vincent Mihalkovic <vmihalko@redhat.com> - 20120801-256
- Do not evaluate arithmetic expressions from environment variables at startup
Resolves: #1790549
Resolves: #2060600
* 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
* Mon Jan 03 2022 Vincent Mihalkovic <vmihalko@redhat.com> - 20120801-255
- Fix race conditions running external commands with job control on
Resolves: #1857847
* Fri Oct 11 2019 Siteshwar Vashisht <svashisht@redhat.com> - 1:2020.0.0-1
- Rebase to 2020.0.0
* Thu Feb 06 2020 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-254
- Bump version number to avoid breaking upgrade path
* Tue Sep 03 2019 Siteshwar Vashisht <svashisht@redhat.com> - 1:2020.0.0-0.4
- Rebase to 2020.0.0-beta1
* Wed Jan 08 2020 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-253
- Do not evaluate arithmetic expressions from environment variables at startup
Resolves: #1790547
* 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
* Tue Oct 16 2018 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-252
- Use autosetup instead of setup in spec file
* 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-251
- Add symlink for rksh
* Wed Apr 17 2019 Siteshwar Vashisht <svashisht@redhat.com> - 1:2020.0.0-0.1
- Rebase to 2020.0.0-alpha1
Resolves: #1700777
* Sun Oct 14 2018 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-250
- Add alternatives switching with mksh
* Fri Feb 01 2019 Fedora Release Engineering <releng@fedoraproject.org> - 20120801-250
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Fri Oct 12 2018 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-249
- Fix annocheck failures
Resolves: #1624125
* 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 Aug 13 2018 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-248
- Fix several defects found by coverity
Resolves: #1610785
* Mon Jun 04 2018 Siteshwar Vashisht <svashisht@redhat.com> - 20120801-247
- Fix a crash caused by memcmp()

View File

@ -1,8 +0,0 @@
--- !Policy
product_versions:
- rhel-9
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tier1.functional}
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}

View File

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

View File

@ -1,162 +0,0 @@
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,79 +0,0 @@
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,14 +0,0 @@
summary:
Run relevant tests from the shell tests repository
discover:
how: fmf
url: https://src.fedoraproject.org/tests/shell
filter: component:ksh
prepare:
how: install
package: ksh
execute:
how: tmt
environment:
PACKAGES: ksh
SH_BIN: ksh

View File

@ -1 +0,0 @@
SHA512 (ksh-1.0.6.tar.gz) = df21b44981701a8e309776bae20df85d5e805bbd4e565259298ebbae1f3ef2c2e9a6e7bd485a8c9ed8a8e41818cedd75a722898f26b8430d830cc199df120dab