diff options
author | Chris Lattner <sabre@nondot.org> | 2009-03-23 05:55:36 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-03-23 05:55:36 +0000 |
commit | eab5cb3b5558407fb715b3c6e2635a4367546e8a (patch) | |
tree | 8a315324afc5551cb45a387eaf96839c282a419e /lib/System/Unix | |
parent | 1c4d8a00aba2b216dfd7c2b95f01752465037d70 (diff) | |
download | external_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.inc | 38 |
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; } |