OSDN Git Service

Delegate SIG_DFL on sigaction to libc.
authorDmitriy Ivanov <dimitry@google.com>
Fri, 3 Apr 2015 01:30:22 +0000 (18:30 -0700)
committerDimitry Ivanov <dimitry@google.com>
Fri, 3 Apr 2015 17:14:19 +0000 (17:14 +0000)
  In the case when user registers SIG_DFL hanlder
  sigchainlib's handler tends to go into infinite loop
  because the function handling signals resets signal
  using by calling to signchain's own implementation.

  This cl fixes the problem by passing sigcations with
  SIG_DFL to the next sigaction (usually libc's).

Bug: 19594886
Change-Id: I9eecf9afd1c7e6d1fe3cd1d4fc506383ecbebe04

sigchainlib/sigchain.cc

index b4bd68b..e61fcd8 100644 (file)
@@ -169,7 +169,8 @@ extern "C" int sigaction(int signal, const struct sigaction* new_action, struct
   // action but don't pass it on to the kernel.
   // Note that we check that the signal number is in range here.  An out of range signal
   // number should behave exactly as the libc sigaction.
-  if (signal > 0 && signal < _NSIG && user_sigactions[signal].IsClaimed()) {
+  if (signal > 0 && signal < _NSIG && user_sigactions[signal].IsClaimed() &&
+      (new_action == nullptr || new_action->sa_handler != SIG_DFL)) {
     struct sigaction saved_action = user_sigactions[signal].GetAction();
     if (new_action != NULL) {
       user_sigactions[signal].SetAction(*new_action, false);
@@ -210,7 +211,7 @@ extern "C" sighandler_t signal(int signal, sighandler_t handler) {
   // action but don't pass it on to the kernel.
   // Note that we check that the signal number is in range here.  An out of range signal
   // number should behave exactly as the libc sigaction.
-  if (signal > 0 && signal < _NSIG && user_sigactions[signal].IsClaimed()) {
+  if (signal > 0 && signal < _NSIG && user_sigactions[signal].IsClaimed() && handler != SIG_DFL) {
     oldhandler = reinterpret_cast<sighandler_t>(user_sigactions[signal].GetAction().sa_handler);
     user_sigactions[signal].SetAction(sa, true);
     return oldhandler;