diff options
author | NRK <nrk@disroot.org> | 2023-01-26 17:26:32 +0100 |
---|---|---|
committer | NRK <nrk@disroot.org> | 2023-01-26 17:26:32 +0100 |
commit | fddad757c6d2645ed7b2d8f64931818d5b3b7a00 (patch) | |
tree | 6334e59d8cb4ef08662006b92ccc5882415567a7 | |
parent | 75849adb88187ab93ab2224706693676a3ea0fb3 (diff) | |
download | nsxiv-fddad757c6d2645ed7b2d8f64931818d5b3b7a00.tar.zst |
don't spoil errno in sig handler (#411)
reported by thread-sanitizer.
the sighandler's spoiled `errno` was causing xlib to incorrectly assume some
error occurred and thus causing the crash described in #391.
to reproduce:
* Open an nsxiv window
* Open another terminal and run the following:
var=$(pidof nsxiv); while :; do kill -s SIGCHLD $var; done
putting the `pid` into a variable is actually important because doing
`$(pidof nsxiv)` inside the loop makes it really hard to reproduce the
issue, I presume because of the extra process invocation it was sending
less SIGCHLD and so putting it into a variable avoids that overhead and
is able to generate more signals.
instead of reaping the zombies manually, we now pass the
`SA_NOCLDSTOP|SA_NOCLDWAIT` for SIGCHLD instead so that the zombies are
reaped automatically.
Closes: https://codeberg.org/nsxiv/nsxiv/issues/391
Reviewed-on: https://codeberg.org/nsxiv/nsxiv/pulls/411
Reviewed-by: explosion-mental <explosion-mental@noreply.codeberg.org>
-rw-r--r-- | main.c | 15 |
1 files changed, 5 insertions, 10 deletions
@@ -843,19 +843,14 @@ static void run(void) } } -static void sigchld(int sig) -{ - while (waitpid(-1, NULL, WNOHANG) > 0); -} - -static void setup_signal(int sig, void (*handler)(int sig)) +static void setup_signal(int sig, void (*handler)(int sig), int flags) { struct sigaction sa; sa.sa_handler = handler; sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_RESTART | SA_NOCLDSTOP; - if (sigaction(sig, &sa, 0) == -1) + sa.sa_flags = flags; + if (sigaction(sig, &sa, NULL) < 0) error(EXIT_FAILURE, errno, "signal %d", sig); } @@ -865,8 +860,8 @@ int main(int argc, char *argv[]) size_t n; const char *homedir, *dsuffix = ""; - setup_signal(SIGCHLD, sigchld); - setup_signal(SIGPIPE, SIG_IGN); + setup_signal(SIGCHLD, SIG_DFL, SA_RESTART|SA_NOCLDSTOP|SA_NOCLDWAIT); + setup_signal(SIGPIPE, SIG_IGN, 0); setlocale(LC_COLLATE, ""); |