1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

DEBUG trap: restore status 2 trigger to skip command (re: d00b4b39)

So now we know what that faulty check for shp->indebug in sh_trap()
was meant to do: it was meant to pass down the trap handler's exit
status, via sh_debug(), down to sh_exec() (xec.c) so that it could
then skip the execution of the next command if the trap's exit
status is 2, as documented in the manual page. As of d00b4b39, exit
status 2 was not passed down, so this stopped working.

This commit reinstates that functionality, but without the exit
status bug in command substitutions caused by the old way.

src/cmd/ksh93/sh/fault.c: sh_trap():
- Save the trap's exit status before restoring the parent
  envionment's exit status. Make this saved exit status the return
  value of the function. (This does not break anything, AFAICT; the
  majority of sh_trap() calls ignore the return value, and the few
  that don't ignore it seem to expect it to return exactly this.)

src/cmd/ksh93/sh/xec.c: sh_exec():
- The sh_trap() fix has one side effect: whereas the exit status of
  a skipped command was always 2 (as per the trap handler), now it
  is always 0, because it gets reset in sh_exec() but no command is
  executed. That is probably not a desirable change in behaviour,
  so let's fix that here instead: set sh.exitval to 2 when skipping
  commands.

src/cmd/ksh93/sh.1:
- Document that ${.sh.command} shell-quotes its arguments for use
  by 'eval' and such. This fact was not documented anywhere, AFAIK.

src/cmd/ksh93/shell.3:
- Document that $? (exit status) is made local to trap handlers.
- Document that sh_trap() returns the trap handler's exit status.

src/cmd/ksh93/tests/basic.sh:
- Add test for this bug.
- Add a missing test for the exit status 255 functionality (if a
  DEBUG trap handler yields this exit status and we're executing a
  function or dot script, a return is triggered).

Fixes: https://github.com/ksh93/ksh/issues/187
This commit is contained in:
Martijn Dekker 2021-02-20 05:13:51 +00:00
parent 2b805f7f1c
commit a959a35291
6 changed files with 56 additions and 3 deletions

View file

@ -662,6 +662,7 @@ got=$(eval 'x=`for i in test; do case $i in test) true;; esac; done`' 2>&1) \
# ======
# Various DEBUG trap fixes: https://github.com/ksh93/ksh/issues/155
# https://github.com/ksh93/ksh/issues/187
# Redirecting disabled the DEBUG trap
exp=$'LINENO: 4\nfoo\nLINENO: 5\nLINENO: 6\nbar\nLINENO: 7\nbaz'
@ -713,6 +714,19 @@ r=`exit 123`
(((e=$?)==123)) || err_exit "DEBUG trap run in \`comsub\` affects exit status (expected 123, got $e)"
trap - DEBUG
# After fixing the previous, the DEBUG trap stopped honouring exit status 2 to skip command execution -- whoops
got=$(
myfn()
{
[[ ${.sh.command} == echo* ]] && return 2
}
trap 'myfn' DEBUG
print end
echo "Hi, I'm a bug"
)
(((e=$?)==2)) && [[ $got == end ]] || err_exit 'DEBUG trap: next command not skipped upon status 2' \
"(got status $e, $(printf %q "$got"))"
# The DEBUG trap was incorrectly inherited by subshells
exp=$'Subshell\nDebug 1\nParentshell'
got=$(
@ -754,5 +768,27 @@ trap - DEBUG # bug compat
[[ $got == "$exp" ]] || err_exit "DEBUG trap not inherited by POSIX function" \
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
# Make sure the DEBUG trap still exits a POSIX function on exit status 255
# TODO: same test for ksh function with -o functrace, once we add that option
exp=$'one\ntwo'
got=$(
myfn()
{
echo one
echo two
echo three
echo four
}
set255()
{
return 255
}
trap '[[ ${.sh.command} == *three ]] && set255' DEBUG
myfn
)
trap - DEBUG # bug compat
[[ $got == "$exp" ]] || err_exit "DEBUG trap did not trigger return from POSIX function on status 255" \
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
# ======
exit $((Errors<125?Errors:125))