From 23de4b25e9285d24cfa21fbed5acd105492866d8 Mon Sep 17 00:00:00 2001 From: Nicolas Despres Date: Wed, 29 Apr 2015 09:33:37 +0200 Subject: Cleanup build on SIGHUP. 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 | 12 +++++++++++- src/subprocess.h | 1 + src/subprocess_test.cc | 24 ++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/subprocess-posix.cc b/src/subprocess-posix.cc index f3baec2..2ddc709 100644 --- a/src/subprocess-posix.cc +++ b/src/subprocess-posix.cc @@ -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)); } diff --git a/src/subprocess.h b/src/subprocess.h index a001fc9..51f40b2 100644 --- a/src/subprocess.h +++ b/src/subprocess.h @@ -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 }; diff --git a/src/subprocess_test.cc b/src/subprocess_test.cc index 07cc52f..066bbb7 100644 --- a/src/subprocess_test.cc +++ b/src/subprocess_test.cc @@ -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". -- cgit v0.12