diff options
author | Nico Weber <nicolasweber@gmx.de> | 2015-03-09 18:32:25 (GMT) |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2015-03-09 18:32:25 (GMT) |
commit | 7370c00c22777786f7f311a45630e3482c4a19e7 (patch) | |
tree | 9db1c626237b976239b5de9c95e067f12eded4b5 | |
parent | 7b9cdfcf81443a2190e9ac4f9246ca227559cc60 (diff) | |
parent | 7b34ee99cdd350511942c2d84fc36ce1696e1686 (diff) | |
download | Ninja-7370c00c22777786f7f311a45630e3482c4a19e7.zip Ninja-7370c00c22777786f7f311a45630e3482c4a19e7.tar.gz Ninja-7370c00c22777786f7f311a45630e3482c4a19e7.tar.bz2 |
Merge pull request #910 from jlnt/master
POSIX: detach background subprocesses from terminal.
-rw-r--r-- | src/subprocess-posix.cc | 7 | ||||
-rw-r--r-- | src/subprocess_test.cc | 31 |
2 files changed, 33 insertions, 5 deletions
diff --git a/src/subprocess-posix.cc b/src/subprocess-posix.cc index 40c9ae1..cc8bff6 100644 --- a/src/subprocess-posix.cc +++ b/src/subprocess-posix.cc @@ -80,8 +80,11 @@ bool Subprocess::Start(SubprocessSet* set, const string& command) { break; if (!use_console_) { - // Put the child in its own process group, so ctrl-c won't reach it. - if (setpgid(0, 0) < 0) + // Put the child in its own session and process group. It will be + // detached from the current terminal and ctrl-c won't reach it. + // Since this process was just forked, it is not a process group leader + // and setsid() will succeed. + if (setsid() < 0) break; // Open /dev/null over stdin. diff --git a/src/subprocess_test.cc b/src/subprocess_test.cc index 8a0787c..76f5c6c 100644 --- a/src/subprocess_test.cc +++ b/src/subprocess_test.cc @@ -16,6 +16,8 @@ #include "test.h" +#include <string> + #ifndef _WIN32 // SetWithLots need setrlimit. #include <stdio.h> @@ -96,12 +98,23 @@ TEST_F(SubprocessTest, InterruptParent) { 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". +// As "ps" will confirm, "yes" could still be connected to a terminal, despite +// not having any of the standard file descriptors be a terminal. +static const char kIsConnectedToTerminal[] = "tty < /dev/tty > /dev/null"; + TEST_F(SubprocessTest, Console) { // Skip test if we don't have the console ourselves. if (isatty(0) && isatty(1) && isatty(2)) { - Subprocess* subproc = subprocs_.Add("test -t 0 -a -t 1 -a -t 2", - /*use_console=*/true); - ASSERT_NE((Subprocess *) 0, subproc); + // Test that stdin, stdout and stderr are a terminal. + // Also check that the current process is connected to a terminal. + Subprocess* subproc = + subprocs_.Add(std::string("test -t 0 -a -t 1 -a -t 2 && ") + + std::string(kIsConnectedToTerminal), + /*use_console=*/true); + ASSERT_NE((Subprocess*)0, subproc); while (!subproc->Done()) { subprocs_.DoWork(); @@ -111,6 +124,18 @@ TEST_F(SubprocessTest, Console) { } } +TEST_F(SubprocessTest, NoConsole) { + Subprocess* subproc = + subprocs_.Add(kIsConnectedToTerminal, /*use_console=*/false); + ASSERT_NE((Subprocess*)0, subproc); + + while (!subproc->Done()) { + subprocs_.DoWork(); + } + + EXPECT_NE(ExitSuccess, subproc->Finish()); +} + #endif TEST_F(SubprocessTest, SetWithSingle) { |