Cleanup build on SIGHUP.
authorNicolas Despres <nicolas.despres@gmail.com>
Wed, 29 Apr 2015 07:33:37 +0000 (09:33 +0200)
committerNicolas Despres <nicolas.despres@gmail.com>
Sun, 20 Sep 2015 13:04:42 +0000 (15:04 +0200)
SIGHUP is sent when the connection hang up (i.e. when the terminal
window is closed or the ssh connection is closed).

src/subprocess-posix.cc
src/subprocess.h
src/subprocess_test.cc

index f3baec2..2ddc709 100644 (file)
@@ -64,6 +64,8 @@ bool Subprocess::Start(SubprocessSet* set, const string& command) {
         break;
       if (sigaction(SIGTERM, &set->old_term_act_, 0) < 0)
         break;
+      if (sigaction(SIGHUP, &set->old_hup_act_, 0) < 0)
+        break;
       if (sigprocmask(SIG_SETMASK, &set->old_mask_, 0) < 0)
         break;
 
@@ -136,7 +138,8 @@ ExitStatus Subprocess::Finish() {
     if (exit == 0)
       return ExitSuccess;
   } else if (WIFSIGNALED(status)) {
-    if (WTERMSIG(status) == SIGINT || WTERMSIG(status) == SIGTERM)
+    if (WTERMSIG(status) == SIGINT || WTERMSIG(status) == SIGTERM
+        || WTERMSIG(status) == SIGHUP)
       return ExitInterrupted;
   }
   return ExitFailure;
@@ -167,6 +170,8 @@ void SubprocessSet::HandlePendingInterruption() {
     interrupted_ = SIGINT;
   else if (sigismember(&pending, SIGTERM))
     interrupted_ = SIGTERM;
+  else if (sigismember(&pending, SIGHUP))
+    interrupted_ = SIGHUP;
 }
 
 SubprocessSet::SubprocessSet() {
@@ -174,6 +179,7 @@ SubprocessSet::SubprocessSet() {
   sigemptyset(&set);
   sigaddset(&set, SIGINT);
   sigaddset(&set, SIGTERM);
+  sigaddset(&set, SIGHUP);
   if (sigprocmask(SIG_BLOCK, &set, &old_mask_) < 0)
     Fatal("sigprocmask: %s", strerror(errno));
 
@@ -184,6 +190,8 @@ SubprocessSet::SubprocessSet() {
     Fatal("sigaction: %s", strerror(errno));
   if (sigaction(SIGTERM, &act, &old_term_act_) < 0)
     Fatal("sigaction: %s", strerror(errno));
+  if (sigaction(SIGHUP, &act, &old_hup_act_) < 0)
+    Fatal("sigaction: %s", strerror(errno));
 }
 
 SubprocessSet::~SubprocessSet() {
@@ -193,6 +201,8 @@ SubprocessSet::~SubprocessSet() {
     Fatal("sigaction: %s", strerror(errno));
   if (sigaction(SIGTERM, &old_term_act_, 0) < 0)
     Fatal("sigaction: %s", strerror(errno));
+  if (sigaction(SIGHUP, &old_hup_act_, 0) < 0)
+    Fatal("sigaction: %s", strerror(errno));
   if (sigprocmask(SIG_SETMASK, &old_mask_, 0) < 0)
     Fatal("sigprocmask: %s", strerror(errno));
 }
index a001fc9..51f40b2 100644 (file)
@@ -98,6 +98,7 @@ struct SubprocessSet {
 
   struct sigaction old_int_act_;
   struct sigaction old_term_act_;
+  struct sigaction old_hup_act_;
   sigset_t old_mask_;
 #endif
 };
index 07cc52f..066bbb7 100644 (file)
@@ -122,6 +122,30 @@ TEST_F(SubprocessTest, InterruptParentWithSigTerm) {
   ASSERT_FALSE("We should have been interrupted");
 }
 
+TEST_F(SubprocessTest, InterruptChildWithSigHup) {
+  Subprocess* subproc = subprocs_.Add("kill -HUP $$");
+  ASSERT_NE((Subprocess *) 0, subproc);
+
+  while (!subproc->Done()) {
+    subprocs_.DoWork();
+  }
+
+  EXPECT_EQ(ExitInterrupted, subproc->Finish());
+}
+
+TEST_F(SubprocessTest, InterruptParentWithSigHup) {
+  Subprocess* subproc = subprocs_.Add("kill -HUP $PPID ; sleep 1");
+  ASSERT_NE((Subprocess *) 0, subproc);
+
+  while (!subproc->Done()) {
+    bool interrupted = subprocs_.DoWork();
+    if (interrupted)
+      return;
+  }
+
+  ASSERT_FALSE("We should have been interrupted");
+}
+
 // A shell command to check if the current process is connected to a terminal.
 // This is different from having stdin/stdout/stderr be a terminal. (For
 // instance consider the command "yes < /dev/null > /dev/null 2>&1".