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:
parent
4df6d674a0
commit
400806afa6
3 changed files with 10 additions and 1 deletions
3
NEWS
3
NEWS
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in a new issue