nsxivfddad75
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.
+5 −10
1 file changed
- M main.c +5 −10
| @@ -843,19 +843,14 @@ static void run(void) | |||
| 843 | 843 | } | |
| 844 | 844 | } | |
| 845 | 845 | ||
| 846 | − | static void sigchld(int sig) | |
| 847 | − | { | |
| 848 | − | while (waitpid(-1, NULL, WNOHANG) > 0); | |
| 849 | − | } | |
| 850 | − | ||
| 851 | − | static void setup_signal(int sig, void (*handler)(int sig)) | |
| 846 | + | static void setup_signal(int sig, void (*handler)(int sig), int flags) | |
| 852 | 847 | { | |
| 853 | 848 | struct sigaction sa; | |
| 854 | 849 | ||
| 855 | 850 | sa.sa_handler = handler; | |
| 856 | 851 | sigemptyset(&sa.sa_mask); | |
| 857 | − | sa.sa_flags = SA_RESTART | SA_NOCLDSTOP; | |
| 858 | − | if (sigaction(sig, &sa, 0) == -1) | |
| 852 | + | sa.sa_flags = flags; | |
| 853 | + | if (sigaction(sig, &sa, NULL) < 0) | |
| 859 | 854 | error(EXIT_FAILURE, errno, "signal %d", sig); | |
| 860 | 855 | } | |
| 861 | 856 | ||
| @@ -865,8 +860,8 @@ int main(int argc, char *argv[]) | |||
| 865 | 860 | size_t n; | |
| 866 | 861 | const char *homedir, *dsuffix = ""; | |
| 867 | 862 | ||
| 868 | − | setup_signal(SIGCHLD, sigchld); | |
| 869 | − | setup_signal(SIGPIPE, SIG_IGN); | |
| 863 | + | setup_signal(SIGCHLD, SIG_DFL, SA_RESTART|SA_NOCLDSTOP|SA_NOCLDWAIT); | |
| 864 | + | setup_signal(SIGPIPE, SIG_IGN, 0); | |
| 870 | 865 | ||
| 871 | 866 | setlocale(LC_COLLATE, ""); | |
| 872 | 867 | ||