Block signals before invoking special or user handlers

1. Block signals marked in sa_mask before invoking user handler
   if not in old style.
2. Block all signals before invoking special signal handler.

Change-Id: Ie1283e97ed28ee3421df584352cd62cb107264bc
Signed-off-by: jgu21 <jinghui.gu@intel.com>
diff --git a/sigchainlib/sigchain.cc b/sigchainlib/sigchain.cc
index c984b17..b76555b 100644
--- a/sigchainlib/sigchain.cc
+++ b/sigchainlib/sigchain.cc
@@ -150,10 +150,15 @@
   // Do we have a managed handler? If so, run it first.
   SpecialSignalHandlerFn managed = user_sigactions[sig].GetSpecialHandler();
   if (managed != nullptr) {
+    sigset_t mask, old_mask;
+    sigfillset(&mask);
+    sigprocmask(SIG_BLOCK, &mask, &old_mask);
     // Call the handler. If it succeeds, we're done.
     if (managed(sig, info, context)) {
+      sigprocmask(SIG_SETMASK, &old_mask, nullptr);
       return;
     }
+    sigprocmask(SIG_SETMASK, &old_mask, nullptr);
   }
 
   const struct sigaction& action = user_sigactions[sig].GetAction();
@@ -166,7 +171,10 @@
     }
   } else {
     if (action.sa_sigaction != nullptr) {
+      sigset_t old_mask;
+      sigprocmask(SIG_BLOCK, &action.sa_mask, &old_mask);
       action.sa_sigaction(sig, info, context);
+      sigprocmask(SIG_SETMASK, &old_mask, nullptr);
     } else {
       signal(sig, SIG_DFL);
       raise(sig);
diff --git a/test/115-native-bridge/nativebridge.cc b/test/115-native-bridge/nativebridge.cc
index 948273a..e9946c8 100644
--- a/test/115-native-bridge/nativebridge.cc
+++ b/test/115-native-bridge/nativebridge.cc
@@ -390,6 +390,20 @@
 #endif
 #endif
 
+static bool cannot_be_blocked(int signum) {
+  // These two sigs cannot be blocked anywhere.
+  if ((signum == SIGKILL) || (signum == SIGSTOP)) {
+      return true;
+  }
+
+  // The invalid rt_sig cannot be blocked.
+  if (((signum >= 32) && (signum < SIGRTMIN)) || (signum > SIGRTMAX)) {
+      return true;
+  }
+
+  return false;
+}
+
 // A dummy special handler, continueing after the faulting location. This code comes from
 // 004-SignalTest.
 static bool nb_signalhandler(int sig, siginfo_t* info ATTRIBUTE_UNUSED, void* context) {
@@ -413,6 +427,23 @@
     UNUSED(context);
 #endif
   }
+
+  // Before invoking this handler, all other unclaimed signals must be blocked.
+  // We're trying to check the signal mask to verify its status here.
+  sigset_t tmpset;
+  sigemptyset(&tmpset);
+  sigprocmask(SIG_SETMASK, nullptr, &tmpset);
+  int other_claimed = (sig == SIGSEGV) ? SIGILL : SIGSEGV;
+  for (int signum = 0; signum < NSIG; ++signum) {
+    if (cannot_be_blocked(signum)) {
+        continue;
+    } else if ((sigismember(&tmpset, signum)) && (signum == other_claimed)) {
+      printf("ERROR: The claimed signal %d is blocked\n", signum);
+    } else if ((!sigismember(&tmpset, signum)) && (signum != other_claimed)) {
+      printf("ERROR: The unclaimed signal %d is not blocked\n", signum);
+    }
+  }
+
   // We handled this...
   return true;
 }