From dd2b587e289603127f30ea296e7751e4cf90fe7d Mon Sep 17 00:00:00 2001
From: Colin Cross <ccross@android.com>
Date: Thu, 12 Jan 2017 20:53:01 -0800
Subject: Close original pipe fd in subprocesses

Non-console subprocesses have the write end of a pipe connected to fds
1 and 2 for stdout and stderr, but they also have the it connected to
whatever fd was assigned in the ninja process when the pipe was
created.  Add a call to posix_spawn_file_actions_addclose after
the posix_spawn_file_actions_adddup2 calls to close the original fd
once it has been dup'd to stdout and stderr.

This fixes an issue seen in the Android build, where one of the
subprocesses is used to start a background helper process.  The
background process attempts to close any inherited fds, but if ninja
used a very large fd number due to a high parallelism count the
background process would not close the fd and ninja would never
consider the subprocess finished.
---
 src/subprocess-posix.cc | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/subprocess-posix.cc b/src/subprocess-posix.cc
index f1f94e5..1de22c3 100644
--- a/src/subprocess-posix.cc
+++ b/src/subprocess-posix.cc
@@ -88,6 +88,8 @@ bool Subprocess::Start(SubprocessSet* set, const string& command) {
       Fatal("posix_spawn_file_actions_adddup2: %s", strerror(errno));
     if (posix_spawn_file_actions_adddup2(&action, output_pipe[1], 2) != 0)
       Fatal("posix_spawn_file_actions_adddup2: %s", strerror(errno));
+    if (posix_spawn_file_actions_addclose(&action, output_pipe[1]) != 0)
+      Fatal("posix_spawn_file_actions_addclose: %s", strerror(errno));
     // In the console case, output_pipe is still inherited by the child and
     // closed when the subprocess finishes, which then notifies ninja.
   }
-- 
cgit v0.12