1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-02-13 03:32:24 +00:00

Do not avoid creating subshell for last command if there are traps

Reproducer:

$ ksh -c 'trap "echo OK" TERM; (kill -s TERM $$)'

Actual output: none
Expected output: OK

The bug is only triggered if 'kill' is executed from a subshell
that is optimised out due to being the last command in the script.

src/cmd/ksh93/sh/xec.c: sh_exec(): case TPAR:
- Instead of only checking for EXIT and ERR traps, do not avoid
  creating a virtual subshell if there are any traps (except DEBUG,
  SIGKILL, SIGSTOP); for this, use the sh.st.trapdontexec flag
  introduced in 40245e08.
This commit is contained in:
Martijn Dekker 2022-07-03 00:54:01 +02:00
parent 4df6d674a0
commit 400806afa6
3 changed files with 10 additions and 1 deletions

3
NEWS
View file

@ -9,6 +9,9 @@ Any uppercase BUG_* names are modernish shell bug IDs.
command that was terminated by a signal, the exit status ($?) of the
subshell did not reflect this by adding 256 to the signal number.
- Fixed a bug that caused signal traps to be ignored if the shell was
signalled from a subshell that is the last command in the script.
2022-07-01:
- In scripts, $COLUMNS and $LINES are now kept up to date in scripts at

View file

@ -1830,7 +1830,7 @@ int sh_exec(register const Shnode_t *t, int flags)
case TPAR:
echeck = 1;
flags &= ~OPTIMIZE_FLAG;
if(!sh.subshell && !sh.st.trapcom[0] && !sh.st.trap[SH_ERRTRAP] && (flags&sh_state(SH_NOFORK)))
if(!sh.subshell && !sh.st.trapdontexec && (flags&sh_state(SH_NOFORK)))
{
/* This is the last command, so avoid creating a subshell */
char *savsig;

View file

@ -1171,5 +1171,11 @@ let "(got=$?)==(exp&0xFF)" || err_exit "fake signal exit from virtual subshell:
(ulimit -t unlimited 2>/dev/null; exit "$exp")
let "(got=$?)==(exp&0xFF)" || err_exit "fake signal exit from real subshell: expected status $((exp&0xFF)), got status $got"
# ======
got=$(set +x; { "$SHELL" -c 'trap "echo OK" TERM; (kill -s TERM $$)'; } 2>&1)
exp=OK
[[ $got == "$exp" ]] || err_exit 'trap ignored when signalled from a subshell that is the last command' \
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
# ======
exit $((Errors<125?Errors:125))