diff --git a/NEWS b/NEWS index 079109f00..13561aa66 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,15 @@ For full details, see the git log at: https://github.com/ksh93/ksh/tree/1.0 Any uppercase BUG_* names are modernish shell bug IDs. +2022-06-13: + +- Trapping a signal that is not a pseudosignal will now cause a virtual + subshell to fork into a real one. This ensures a persistent PID where + other processes can signal the subshell (the PID of a virtual subshell may + change as other commands cause it to fork), and fixes a bug where a signal + could not be correctly or effectively trapped in a subshell if the same + signal was also trapped in the main shell environment. + 2022-06-12: - The POSIX mode now disables zero-padding of seconds in 'time'/'times' output. diff --git a/src/cmd/ksh93/bltins/trap.c b/src/cmd/ksh93/bltins/trap.c index c19d1ef65..76e134de8 100644 --- a/src/cmd/ksh93/bltins/trap.c +++ b/src/cmd/ksh93/bltins/trap.c @@ -166,6 +166,13 @@ int b_trap(int argc,char *argv[],Shbltin_t *context) } else { + /* + * Trap or ignore a real signal. A virtual subshell needs to fork in + * order to receive signals correctly and (because other commands + * may cause a virtual subshell to fork) to ensure a persistent PID. + */ + if(sh.subshell && !sh.subshare) + sh_subfork(); if(sig >= sh.st.trapmax) sh.st.trapmax = sig+1; arg = sh.st.trapcom[sig]; diff --git a/src/cmd/ksh93/include/version.h b/src/cmd/ksh93/include/version.h index 1896808d6..cfa451acd 100644 --- a/src/cmd/ksh93/include/version.h +++ b/src/cmd/ksh93/include/version.h @@ -23,7 +23,7 @@ #define SH_RELEASE_FORK "93u+m" /* only change if you develop a new ksh93 fork */ #define SH_RELEASE_SVER "1.0.0-beta.2" /* semantic version number: https://semver.org */ -#define SH_RELEASE_DATE "2022-06-12" /* must be in this format for $((.sh.version)) */ +#define SH_RELEASE_DATE "2022-06-13" /* must be in this format for $((.sh.version)) */ #define SH_RELEASE_CPYR "(c) 2020-2022 Contributors to ksh " SH_RELEASE_FORK /* Scripts sometimes field-split ${.sh.version}, so don't change amount of whitespace. */ diff --git a/src/cmd/ksh93/tests/signal.sh b/src/cmd/ksh93/tests/signal.sh index 3dc23fd4b..9d4b34ae8 100755 --- a/src/cmd/ksh93/tests/signal.sh +++ b/src/cmd/ksh93/tests/signal.sh @@ -273,22 +273,37 @@ PATH=${PATH#:} if [[ ${SIG[USR1]} ]] then float s=$SECONDS exp=SIGUSR1 + got=$(LC_ALL=C $SHELL -c ' trap "print SIGUSR1 ; exit 0" USR1 (trap "" USR1 ; exec kill -USR1 $$ & sleep .5) print done') [[ $got == "$exp" ]] || err_exit 'subshell ignoring signal does not send signal to parent' \ - "(expected '$exp', got '$got')" + "(expected $(printf %q "$exp"), got $(printf %q "$got"))" (( (SECONDS-s) < .4 )) && err_exit 'parent does not wait for child to complete before handling signal' ((s = SECONDS)) - exp=SIGUSR1 + + : >out + trap 'echo SIGUSR1 >out; exit 0' USR1 + (trap '' USR1; kill -USR1 $$) + got=$(out + trap 'echo SIGUSR1 >out; exit 0' USR1 + (trap 'echo wrong' USR1; kill -USR1 $$) + got=$(