From eae1b7f862ae45e7898304cd81332f12bd8fbdf7 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Wed, 21 Apr 2004 12:51:27 +0000 Subject: [PATCH] - ls could incorrectly restore color if multiple signals arrived nearly simultaneously. (main): Rewrite signal-catching code to make it similar to other coreutils programs. When processing signals, block all signals that we catch, but do not block signals that we don't catch. Avoid problems with unsigned int warnings. (sighandler) [defined SA_NOCLDSTOP]: Use simpler "signal (sig, SIG_DFL)" rather than sigaction equivalent. (sighandler) [!defined SA_NOCLDSTOP]: Reset signal handler to self, not to SIG_IGN, since SIGTSTP can be received more than once. (main): Use SA_RESTART, as that is simpler than checking for EINTR failures all over the place. --- src/ls.c | 65 +++++++++++++++++++++++--------------------------------- 1 file changed, 26 insertions(+), 39 deletions(-) diff --git a/src/ls.c b/src/ls.c index 74d8cd4777..a96cdbaf89 100644 --- a/src/ls.c +++ b/src/ls.c @@ -973,33 +973,19 @@ restore_default_color (void) static void sighandler (int sig) { + /* SIGTSTP is special, since the application can receive that signal more + than once. In this case, don't set the signal handler to the default. + Instead, just raise the uncatchable SIGSTOP. */ #ifndef SA_NOCLDSTOP - signal (sig, SIG_IGN); + signal (sig, sig == SIGTSTP ? sighandler : SIG_IGN); #endif restore_default_color (); - /* SIGTSTP is special, since the application can receive that signal more - than once. In this case, don't set the signal handler to the default. - Instead, just raise the uncatchable SIGSTOP. */ if (sig == SIGTSTP) - { - sig = SIGSTOP; - } + sig = SIGSTOP; else - { -#ifdef SA_NOCLDSTOP - struct sigaction sigact; - - sigact.sa_handler = SIG_DFL; - sigemptyset (&sigact.sa_mask); - sigact.sa_flags = 0; - sigaction (sig, &sigact, NULL); -#else - signal (sig, SIG_DFL); -#endif - } - + signal (sig, SIG_DFL); raise (sig); } @@ -1043,34 +1029,35 @@ main (int argc, char **argv) check_symlink_color = 1; { - unsigned int j; - static int const sigs[] = { SIGHUP, SIGINT, SIGPIPE, - SIGQUIT, SIGTERM, SIGTSTP }; - unsigned int nsigs = sizeof sigs / sizeof *sigs; + int j; + static int const sig[] = { SIGHUP, SIGINT, SIGPIPE, + SIGQUIT, SIGTERM, SIGTSTP }; + enum { nsigs = sizeof sig / sizeof sig[0] }; + #ifdef SA_NOCLDSTOP - struct sigaction oldact, newact; + struct sigaction act; sigset_t caught_signals; sigemptyset (&caught_signals); for (j = 0; j < nsigs; j++) - sigaddset (&caught_signals, sigs[j]); - newact.sa_handler = sighandler; - newact.sa_mask = caught_signals; - newact.sa_flags = 0; -#endif + { + sigaction (sig[j], NULL, &act); + if (act.sa_handler != SIG_IGN) + sigaddset (&caught_signals, sig[j]); + } + + act.sa_handler = sighandler; + act.sa_mask = caught_signals; + act.sa_flags = SA_RESTART; for (j = 0; j < nsigs; j++) - { - int sig = sigs[j]; -#ifdef SA_NOCLDSTOP - sigaction (sig, NULL, &oldact); - if (oldact.sa_handler != SIG_IGN) - sigaction (sig, &newact, NULL); + if (sigismember (&caught_signals, sig[j])) + sigaction (sig[j], &act, NULL); #else - if (signal (sig, SIG_IGN) != SIG_IGN) - signal (sig, sighandler); + for (j = 0; j < nsigs; j++) + if (signal (sig[j], SIG_IGN) != SIG_IGN) + signal (sig[j], sighandler); #endif - } } } -- 2.47.2