Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Differences between "TRAPERR()" and "trap foo ERR"
- X-seq: zsh-users 26820
- From: Zach Riggle <zachriggle@xxxxxxxxx>
- To: zsh-users@xxxxxxx
- Subject: Differences between "TRAPERR()" and "trap foo ERR"
- Date: Tue, 27 Jul 2021 22:47:16 -0500
- Archived-at: <https://zsh.org/users/26820>
- List-id: <zsh-users.zsh.org>
--------------------------------- BACKGROUND ---------------------------------
I've discovered some undocumented behavior of TRAPNAL functions, and
some divergence of behavior between TRAPNAL and "trap foo NAL".
Specifically, the former receives a $1 with the value of the signal
which invoked the routine, but the latter does not -- and that value
is the actual value of the signal (e.g. $1 == SIGSEGV == 11 for
TRAPSEGV).
For example, TRAPERR receives a value of 32, which is not a valid
signal value on my system (NSIG==32).
When setting via "trap 'my_trapfunc $@' SEGV", no argument is provided
to 'my_trapfunc'.
All of this is on ZSH v5.8.
---------------------------------- EXAMPLES ----------------------------------
So I've got two scripts, traperr and trapfunc.
$ cat traperr
#!/usr/bin/env zsh
TRAPERR() {
echo "Got ${(q-)@}"
}
false
$ cat trapfunc
#!/usr/bin/env zsh
trap_err() {
echo "Got ${(q-)@}"
}
trap trap_err ERR
false
Note that "traperr" declares an all-caps TRAPERR. "trapfunc" instead
uses the "trap" command to set the ERR trap.
Both generally work as expected, but the former ("TRAPERR") receives
an argument in "$1" that is undocumented.
$ ./traperr
Got 32
$ ./trapfunc
Got
------------------------------- DOCUMENTATION --------------------------------
I looked at the manual page (section 9.3.1) for trap functions:
https://zsh.sourceforge.io/Doc/Release/Functions.html#Trap-Functions
However, there's nothing mentioned about any parameters being
specified to TRAPNAL functions, and it generally seems that "TRAPNAL"
and "trap foo NAL" behave the same.
------------------------------ EXPERIMENTATION -------------------------------
At first, I thought the provenance of the value 32 comes from the
value of NSIG on my system (which on macOS is 32).
$ cat nsig.c
#include <stdio.h>
#include <signal.h>
int main() {
printf("NSIG = %d\n", NSIG);
}
$ gcc -o nsig nsig.c
$ ./nsig
NSIG = 32
Second, I thought that perhaps it might come from ZSH's own list of
signals. There is a ZERR entry, in any case.
$ echo $signals
EXIT HUP ... ZERR DEBUG
$ for i in {0..${#signals}}; do echo "$i: ${signals[$i]}"; done
0:
1: EXIT
2: HUP
...
31: USR1
32: USR2
33: ZERR
34: DEBUG
As we can see here, the value received by "33: ZERR", is not the 32'th
entry in the list of $signals. Since ZSH array indices start at 1,
this makes more sense and getting "32" for ZERR, is correct.
This is confirmed by setting e.g. TRAPSEGV, where SIGSEGV==11.
$ cat trapsegv
#!/usr/bin/env zsh
TRAPSEGV() {
echo "Got ${(q-)@}"
}
kill -s SEGV $$
$ ./trapsegv
Got 11
So we are receiving the actual value of the signal, when we declare a
TRAPNAL function. This corresponds to the NAL+1'th offset in the
$signals array.
--------------------- ATTEMPT TO CONVERGE FUNCTIONALITY ----------------------
Since arguments are being provided to TRAPNAL functions, I thought I
would try to modify the "trapfunc" script to include its arguments
when invoking trap_err (note the extra $@ inside the trap statement
versus before).
$ cat trapfunc_args
#!/usr/bin/env zsh
trap_err() {
echo "Got ${(q-)@}"
}
trap 'trap_err $@' ERR
false
$ ./trapfunc_args
Got
It seems this does not work to specify the signal number by including
e.g. $@ in the trap command list.
------------------------ CONCLUSION AND OBSERVATIONS -------------------------
Overall, there are two observations.
1. The behavior that TRAPNAL will receive NAL as its first argument,
where NAL corresponds to a the system-defined signal values (e.g.
SIGSEGV == 11). The name for this signal can be gotten from
${signals[x+1]}. This should be documented.
2. This behavior does not expand to "trap func NAL" statements, even
if we try to pass "$@" to some function. This seems like a bug.
Am I missing something in the docs (quite likely) -- and is the
behavior difference intended -- or are these bugs.
Thanks for reading!
Zach Riggle
Messages sorted by:
Reverse Date,
Date,
Thread,
Author