summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2004-04-21 12:51:27 +0000
committerJim Meyering <jim@meyering.net>2004-04-21 12:51:27 +0000
commiteae1b7f862ae45e7898304cd81332f12bd8fbdf7 (patch)
treed88633fead412ecac5a3d6253a5865370460f43e /src
parent4441496397d003bdae8bfe21c4546d3ea02dcee2 (diff)
downloadcoreutils-eae1b7f862ae45e7898304cd81332f12bd8fbdf7.tar.xz
- 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.
Diffstat (limited to 'src')
-rw-r--r--src/ls.c65
1 files changed, 26 insertions, 39 deletions
diff --git a/src/ls.c b/src/ls.c
index 74d8cd477..a96cdbaf8 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
- }
}
}