aboutsummaryrefslogtreecommitdiffstats
path: root/lib/System/Unix
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-03-23 05:55:36 +0000
committerChris Lattner <sabre@nondot.org>2009-03-23 05:55:36 +0000
commiteab5cb3b5558407fb715b3c6e2635a4367546e8a (patch)
tree8a315324afc5551cb45a387eaf96839c282a419e /lib/System/Unix
parent1c4d8a00aba2b216dfd7c2b95f01752465037d70 (diff)
downloadexternal_llvm-eab5cb3b5558407fb715b3c6e2635a4367546e8a.zip
external_llvm-eab5cb3b5558407fb715b3c6e2635a4367546e8a.tar.gz
external_llvm-eab5cb3b5558407fb715b3c6e2635a4367546e8a.tar.bz2
When we restore signal handlers, restore them back to what they
were when we came around, not to their default handler. This should fix PR3848 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@67509 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/System/Unix')
-rw-r--r--lib/System/Unix/Signals.inc38
1 files changed, 30 insertions, 8 deletions
diff --git a/lib/System/Unix/Signals.inc b/lib/System/Unix/Signals.inc
index 60e3a26..dc3910c 100644
--- a/lib/System/Unix/Signals.inc
+++ b/lib/System/Unix/Signals.inc
@@ -57,23 +57,45 @@ static const int KillSigs[] = {
static const int *const KillSigsEnd =
KillSigs + sizeof(KillSigs) / sizeof(KillSigs[0]);
-// Just call signal
+static unsigned NumRegisteredSignals = 0;
+static struct {
+ struct sigaction SA;
+ int SigNo;
+} RegisteredSignalInfo[(sizeof(IntSigs)+sizeof(KillSigs))/sizeof(KillSigs[0])];
+
+
static void RegisterHandler(int Signal) {
- signal(Signal, SignalHandler);
+ assert(NumRegisteredSignals <
+ sizeof(RegisteredSignalInfo)/sizeof(RegisteredSignalInfo[0]) &&
+ "Out of space for signal handlers!");
+
+ struct sigaction NewHandler;
+
+ NewHandler.sa_handler = SignalHandler;
+ NewHandler.sa_flags = SA_NODEFER|SA_RESETHAND;
+ sigemptyset(&NewHandler.sa_mask);
+
+ // Install the new handler, save the old one in RegisteredSignalInfo.
+ sigaction(Signal, &NewHandler,
+ &RegisteredSignalInfo[NumRegisteredSignals].SA);
+ RegisteredSignalInfo[NumRegisteredSignals].SigNo = Signal;
+ ++NumRegisteredSignals;
}
static void RegisterHandlers() {
+ // If the handlers are already registered, we're done.
+ if (NumRegisteredSignals != 0) return;
+
std::for_each(IntSigs, IntSigsEnd, RegisterHandler);
std::for_each(KillSigs, KillSigsEnd, RegisterHandler);
}
-static void UnregisterHandler(int Signal) {
- signal(Signal, SIG_DFL);
-}
-
static void UnregisterHandlers() {
- std::for_each(KillSigs, KillSigsEnd, UnregisterHandler);
- std::for_each(IntSigs, IntSigsEnd, UnregisterHandler);
+ // Restore all of the signal handlers to how they were before we showed up.
+ for (unsigned i = 0, e = NumRegisteredSignals; i != e; ++i)
+ sigaction(RegisteredSignalInfo[NumRegisteredSignals].SigNo,
+ &RegisteredSignalInfo[NumRegisteredSignals].SA, 0);
+ NumRegisteredSignals = 0;
}