summaryrefslogtreecommitdiffstats
path: root/src/subprocess-posix.cc
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2014-01-30 05:57:58 (GMT)
committerPeter Collingbourne <peter@pcc.me.uk>2014-02-03 05:20:01 (GMT)
commit2832613dc7c1a4a8ff3b9df729954715762a8381 (patch)
tree7f4be6edb18f26d73af002f977c2f4a901dfe2ea /src/subprocess-posix.cc
parent84986af6fdeae3f649f2bf884b20f644bc370e48 (diff)
downloadNinja-2832613dc7c1a4a8ff3b9df729954715762a8381.zip
Ninja-2832613dc7c1a4a8ff3b9df729954715762a8381.tar.gz
Ninja-2832613dc7c1a4a8ff3b9df729954715762a8381.tar.bz2
Introduce the "console" pool
This is a pre-defined pool with a depth of 1. It has the special property that any task in the pool has direct access to the console. This can be useful for interactive tasks or long-running tasks which produce status updates on the console (such as test suites).
Diffstat (limited to 'src/subprocess-posix.cc')
-rw-r--r--src/subprocess-posix.cc50
1 files changed, 28 insertions, 22 deletions
diff --git a/src/subprocess-posix.cc b/src/subprocess-posix.cc
index a9af756..793d48f 100644
--- a/src/subprocess-posix.cc
+++ b/src/subprocess-posix.cc
@@ -25,7 +25,8 @@
#include "util.h"
-Subprocess::Subprocess() : fd_(-1), pid_(-1) {
+Subprocess::Subprocess(bool use_console) : fd_(-1), pid_(-1),
+ use_console_(use_console) {
}
Subprocess::~Subprocess() {
if (fd_ >= 0)
@@ -58,29 +59,31 @@ bool Subprocess::Start(SubprocessSet* set, const string& command) {
// Track which fd we use to report errors on.
int error_pipe = output_pipe[1];
do {
- if (setpgid(0, 0) < 0)
- break;
-
if (sigaction(SIGINT, &set->old_act_, 0) < 0)
break;
if (sigprocmask(SIG_SETMASK, &set->old_mask_, 0) < 0)
break;
- // Open /dev/null over stdin.
- int devnull = open("/dev/null", O_RDONLY);
- if (devnull < 0)
- break;
- if (dup2(devnull, 0) < 0)
- break;
- close(devnull);
-
- if (dup2(output_pipe[1], 1) < 0 ||
- dup2(output_pipe[1], 2) < 0)
- break;
-
- // Now can use stderr for errors.
- error_pipe = 2;
- close(output_pipe[1]);
+ if (!use_console_) {
+ if (setpgid(0, 0) < 0)
+ break;
+
+ // Open /dev/null over stdin.
+ int devnull = open("/dev/null", O_RDONLY);
+ if (devnull < 0)
+ break;
+ if (dup2(devnull, 0) < 0)
+ break;
+ close(devnull);
+
+ if (dup2(output_pipe[1], 1) < 0 ||
+ dup2(output_pipe[1], 2) < 0)
+ break;
+
+ // Now can use stderr for errors.
+ error_pipe = 2;
+ close(output_pipe[1]);
+ }
execl("/bin/sh", "/bin/sh", "-c", command.c_str(), (char *) NULL);
} while (false);
@@ -168,8 +171,8 @@ SubprocessSet::~SubprocessSet() {
Fatal("sigprocmask: %s", strerror(errno));
}
-Subprocess *SubprocessSet::Add(const string& command) {
- Subprocess *subprocess = new Subprocess;
+Subprocess *SubprocessSet::Add(const string& command, bool use_console) {
+ Subprocess *subprocess = new Subprocess(use_console);
if (!subprocess->Start(this, command)) {
delete subprocess;
return 0;
@@ -279,7 +282,10 @@ Subprocess* SubprocessSet::NextFinished() {
void SubprocessSet::Clear() {
for (vector<Subprocess*>::iterator i = running_.begin();
i != running_.end(); ++i)
- kill(-(*i)->pid_, SIGINT);
+ // Since the foreground process is in our process group, it will receive a
+ // SIGINT at the same time as us.
+ if (!(*i)->use_console_)
+ kill(-(*i)->pid_, SIGINT);
for (vector<Subprocess*>::iterator i = running_.begin();
i != running_.end(); ++i)
delete *i;