// Track which fd we use to report errors on.
int error_pipe = output_pipe[1];
do {
- if (sigaction(SIGINT, &set->old_act_, 0) < 0)
+ if (sigaction(SIGINT, &set->old_int_act_, 0) < 0)
+ break;
+ if (sigaction(SIGTERM, &set->old_term_act_, 0) < 0)
break;
if (sigprocmask(SIG_SETMASK, &set->old_mask_, 0) < 0)
break;
if (exit == 0)
return ExitSuccess;
} else if (WIFSIGNALED(status)) {
- if (WTERMSIG(status) == SIGINT)
+ if (WTERMSIG(status) == SIGINT || WTERMSIG(status) == SIGTERM)
return ExitInterrupted;
}
return ExitFailure;
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGINT);
+ sigaddset(&set, SIGTERM);
if (sigprocmask(SIG_BLOCK, &set, &old_mask_) < 0)
Fatal("sigprocmask: %s", strerror(errno));
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_handler = SetInterruptedFlag;
- if (sigaction(SIGINT, &act, &old_act_) < 0)
+ if (sigaction(SIGINT, &act, &old_int_act_) < 0)
+ Fatal("sigaction: %s", strerror(errno));
+ if (sigaction(SIGTERM, &act, &old_term_act_) < 0)
Fatal("sigaction: %s", strerror(errno));
}
SubprocessSet::~SubprocessSet() {
Clear();
- if (sigaction(SIGINT, &old_act_, 0) < 0)
+ if (sigaction(SIGINT, &old_int_act_, 0) < 0)
+ Fatal("sigaction: %s", strerror(errno));
+ if (sigaction(SIGTERM, &old_term_act_, 0) < 0)
Fatal("sigaction: %s", strerror(errno));
if (sigprocmask(SIG_SETMASK, &old_mask_, 0) < 0)
Fatal("sigprocmask: %s", strerror(errno));
ASSERT_FALSE("We should have been interrupted");
}
+TEST_F(SubprocessTest, InterruptChildWithSigTerm) {
+ Subprocess* subproc = subprocs_.Add("kill -TERM $$");
+ ASSERT_NE((Subprocess *) 0, subproc);
+
+ while (!subproc->Done()) {
+ subprocs_.DoWork();
+ }
+
+ EXPECT_EQ(ExitInterrupted, subproc->Finish());
+}
+
+TEST_F(SubprocessTest, InterruptParentWithSigTerm) {
+ Subprocess* subproc = subprocs_.Add("kill -TERM $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".
}
ASSERT_EQ(kNumProcs, subprocs_.finished_.size());
}
-#endif // !__APPLE__ && !_WIN32
+#endif // !__APPLE__ && !_WIN32
// TODO: this test could work on Windows, just not sure how to simply
// read stdin.