summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Despres <nicolas.despres@gmail.com>2014-04-16 10:08:42 +0200
committerNicolas Despres <nicolas.despres@gmail.com>2015-04-24 17:42:59 +0200
commit9fff9551b2f3d3e5c994512b06832b40560d510b (patch)
tree013a6eda9af77438bce692df0e88ebb426cf19e9
parentb4bc5cf7c924be251a5c8abdfca58f47c3f5c185 (diff)
downloadninja-9fff9551b2f3d3e5c994512b06832b40560d510b.tar.gz
Forward interruption signal to child processes.
-rw-r--r--src/subprocess-posix.cc56
-rw-r--r--src/subprocess.h7
2 files changed, 34 insertions, 29 deletions
diff --git a/src/subprocess-posix.cc b/src/subprocess-posix.cc
index c784a39..f3baec2 100644
--- a/src/subprocess-posix.cc
+++ b/src/subprocess-posix.cc
@@ -25,20 +25,6 @@
#include "util.h"
-namespace {
-
-bool HasPendingInterruption() {
- sigset_t pending;
- sigemptyset(&pending);
- if (sigpending(&pending) == -1) {
- perror("ninja: sigpending");
- return false;
- }
- return sigismember(&pending, SIGINT);
-}
-
-} // anonymous namespace
-
Subprocess::Subprocess(bool use_console) : fd_(-1), pid_(-1),
use_console_(use_console) {
}
@@ -164,11 +150,23 @@ const string& Subprocess::GetOutput() const {
return buf_;
}
-bool SubprocessSet::interrupted_;
+int SubprocessSet::interrupted_;
void SubprocessSet::SetInterruptedFlag(int signum) {
- (void) signum;
- interrupted_ = true;
+ interrupted_ = signum;
+}
+
+void SubprocessSet::HandlePendingInterruption() {
+ sigset_t pending;
+ sigemptyset(&pending);
+ if (sigpending(&pending) == -1) {
+ perror("ninja: sigpending");
+ return;
+ }
+ if (sigismember(&pending, SIGINT))
+ interrupted_ = SIGINT;
+ else if (sigismember(&pending, SIGTERM))
+ interrupted_ = SIGTERM;
}
SubprocessSet::SubprocessSet() {
@@ -224,17 +222,18 @@ bool SubprocessSet::DoWork() {
++nfds;
}
- interrupted_ = false;
+ interrupted_ = 0;
int ret = ppoll(&fds.front(), nfds, NULL, &old_mask_);
if (ret == -1) {
if (errno != EINTR) {
perror("ninja: ppoll");
return false;
}
- return interrupted_;
+ return IsInterrupted();
}
- if (HasPendingInterruption())
+ HandlePendingInterruption();
+ if (IsInterrupted())
return true;
nfds_t cur_nfd = 0;
@@ -255,7 +254,7 @@ bool SubprocessSet::DoWork() {
++i;
}
- return interrupted_;
+ return IsInterrupted();
}
#else // !defined(USE_PPOLL)
@@ -274,17 +273,18 @@ bool SubprocessSet::DoWork() {
}
}
- interrupted_ = false;
+ interrupted_ = 0;
int ret = pselect(nfds, &set, 0, 0, 0, &old_mask_);
if (ret == -1) {
if (errno != EINTR) {
perror("ninja: pselect");
return false;
}
- return interrupted_;
+ return IsInterrupted();
}
- if (HasPendingInterruption())
+ HandlePendingInterruption();
+ if (IsInterrupted())
return true;
for (vector<Subprocess*>::iterator i = running_.begin();
@@ -301,7 +301,7 @@ bool SubprocessSet::DoWork() {
++i;
}
- return interrupted_;
+ return IsInterrupted();
}
#endif // !defined(USE_PPOLL)
@@ -316,10 +316,10 @@ Subprocess* SubprocessSet::NextFinished() {
void SubprocessSet::Clear() {
for (vector<Subprocess*>::iterator i = running_.begin();
i != running_.end(); ++i)
- // Since the foreground process is in our process group, it will receive a
- // SIGINT at the same time as us.
+ // Since the foreground process is in our process group, it will receive
+ // the interruption signal (i.e. SIGINT or SIGTERM) at the same time as us.
if (!(*i)->use_console_)
- kill(-(*i)->pid_, SIGINT);
+ kill(-(*i)->pid_, interrupted_);
for (vector<Subprocess*>::iterator i = running_.begin();
i != running_.end(); ++i)
delete *i;
diff --git a/src/subprocess.h b/src/subprocess.h
index daeeef6..a001fc9 100644
--- a/src/subprocess.h
+++ b/src/subprocess.h
@@ -89,7 +89,12 @@ struct SubprocessSet {
static HANDLE ioport_;
#else
static void SetInterruptedFlag(int signum);
- static bool interrupted_;
+ static void HandlePendingInterruption();
+ /// Store the signal number that causes the interruption.
+ /// 0 if not interruption.
+ static int interrupted_;
+
+ static bool IsInterrupted() { return interrupted_ != 0; }
struct sigaction old_int_act_;
struct sigaction old_term_act_;