Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -O2 -g -pipe -Wall -Werror=format-security
-Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions
-fstack-protector-strong -grecord-gcc-switches
-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1
-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic
-fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection
-Wno-parentheses -Wno-format-security
uname output: Linux chatoyancy 5.1.20-300.fc30.x86_64 #1 SMP Fri Jul
26 15:03:11 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
Machine Type: x86_64-redhat-linux-gnu
Bash Version: 5.0
Patch Level: 11
Release Status: release
Summary:
The behavior of no-argument `return' in trap handlers has been
changed from Bash 4.4 to follow the description of POSIX. Recently
this behavior caused problems in my Bash script. I am wondering
whether this change actually matches with the behavior meant by
POSIX because the change introduces unreasonable constraints in
writing shell functions.
For the condition of this special treatment of `return', POSIX says
``When return is executed in a trap action''. Here are two possible
interpretation: (A) `return's specified in the argument string of
`trap' builtin are affected, or (B) all the `return's in entire
runtime function-call tree in trap processing are affected. I guess
that POSIX wanted to provide a way to exit functions that received
signals without changing the value of `$?'. If that is the case,
the POSIX should have meant (A). However, the current Bash
implementation behaves as if it follows the interpretation (B).
I would like to hear what do you think of this.
Description:
In the latest release of Bash 5.0.16 and in the current devel
branch, when function calls in trap handlers are terminated by
no-argument `return' builtin, the exit status is always the value of
$? at the moment that the trap handler started. This behavior was
introduced in Bash 4.4.
I noticed this behavior in debugging an infinite loop caused by
SIGWINCH reported at https://github.com/akinomyoga/ble.sh/issues/48.
The structure of the code related to the infinite loop can be
summarized in the following small script.
#!/bin/bash
function check_loop_condition {
if ((index++%10==0)); then
echo index=$index
((index<100))
return # *** return exit status of the previous command ***
fi
: do something
return 0
}
function update {
local index=0
while check_loop_condition; do :; done
}
trap 'update' USR1
kill -USR1 $$
If the function `update' is called normally (outside of trap
handlers), it will print the numbers {1..101..10} and terminate
soon. However, when it is called in trap handlers, it falls into an
infinite loop in Bash 4.4+. This is because the no-argument
`return' in the function `check_loop_condition' always returns `$?'
before the trap started regardless of the exit status of
`((index<100))'.
If all the `return's in the entire function-call tree are affected
in trap processing as in the interpretation (B), one cannot reliably
use no-argument `return' to return the last-command exit status. To
avoid the problem, one has to always write the exit status
explicitly as `return $?', and there is no use case for no-argument
`return' at all. I don't think this is meant by POSIX which defines
the behavior of no-argument `return' explicitly. Or, maybe one
cannot use shell functions in trap handlers. Note that in my
script, I need to re-render the terminal contents on SIGWINCH so
that I need to run complicated shell programs implemented as shell
functions. POSIX does not prohibit the use of shell functions in
trap handlers.
Here I checked how the behavior was changed in Bash 4.4. The
related commits are 939d190e0 (commit bash-20140314 snapshot) and
e2f12fdf5 (commit bash-20140321 snapshot). The relevant ChangeLog
is quoted as follows:
>3/11
>
>
> builtins/common.c
> - get_exitstat: when running `return' in a trap action, and it is not
> supplied an argument, use the saved exit status in
> trap_saved_exit_value. Fixes Posix problem reported by
> Eduardo A. Bustamante L坦pez
>
>
>3/18
>
>
> builtins/common.c
> - get_exitstat: update fix of 3/11 to allow the DEBUG trap to use the
> current value of $? instead of the value it had before the trap
> action was run. This is one reason the DEBUG trap exists, and
> extended debug mode uses it. Might want to do this only in Posix
> mode
This change is made after the following discussion:
https://lists.gnu.org/archive/html/bug-bash/2014-03/msg00053.html
Taking the f