[Toybox] Confused by bash trap handler return value.

Chet Ramey chet.ramey at case.edu
Wed Feb 12 07:27:49 PST 2025


On 2/11/25 6:41 PM, Rob Landley wrote:
> On 2/11/25 08:34, Chet Ramey wrote:
>> On 2/10/25 7:25 PM, Rob Landley wrote:
>>> I don't understand how to reconcile the behavior of all three of these 
>>> in debian's bash 5.2.15(1):
>>
>> Trap actions have no "return value." POSIX says:
>>
>> "The value of "$?" after the trap action completes shall be the value it
>> had before the trap action was executed."
> 
> Ok, I can do that. Thanks.
> 
> The question is how to TEST it...

Testing that trap actions preserve $? is not hard. This had better not
echo 1.

trap 'echo WINCH ; false' WINCH
(exit 41)       # force $? to something neither 0 nor 1
kill -WINCH $$
# add this if you're concerned that kill will finish before the SIGWINCH
# arrives, since it will cause multiple system calls
(exit 42)
echo $?

The trap won't get run until after the kill returns; trap actions are
not run asynchronously. There's a potential race condition, but I don't
think it will ever get hit.

> 
>>> 3) The previous statement returns 1 and the trap handler returns 1, so 
>>> the next statement sees zero...?
>>
>> The AND-OR list returns 0, since the trap command succeeds, the kill
>> command runs, and kill returns 0 if it sends at least one signal
>> successfully. That is documented:
>>
>> "kill returns true if at least one signal was successfully  sent,
>>   or false if an error occurs or an invalid option is encountered."
> 
> /bin/kill from procps is returning 1 if an error occurred (because a "PID 
> does not exist" error occurs), bash kill is returning 0 because at least 
> one signal was successfully sent (despite an error having occurred). Their 
> behavior differs because you can read the above either way. (You're reading 
> the or as a short circuit operator, they're probably reading the "at least 
> one" as meaning "kill -s USR1" should return error and "return false if an 
> error occurs" as a mandate.)

The POSIX language is ambiguous, the difference is between "fail if any
kill fails" vs. "succeed if any kill succeeds."

> I suppose I can implement a 0 return code for the kill builtin and a 1 
> return code if it's called via the $PATH, but... ew?

I'm going to change it for POSIX mode, since that's compatible with what
other POSIX shells have implemented. Bash default mode will stay the same.

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
		 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU    chet at case.edu    http://tiswww.cwru.edu/~chet/


More information about the Toybox mailing list