OSDN Git Service

When we restore signal handlers, restore them back to what they
authorChris Lattner <sabre@nondot.org>
Mon, 23 Mar 2009 05:55:36 +0000 (05:55 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 23 Mar 2009 05:55:36 +0000 (05:55 +0000)
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

lib/System/Unix/Signals.inc

index 60e3a26..dc3910c 100644 (file)
@@ -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;
 }