aboutsummaryrefslogtreecommitdiffstats
path: root/executor
diff options
context:
space:
mode:
Diffstat (limited to 'executor')
-rw-r--r--executor/executor_runner.h6
-rw-r--r--executor/subprocess.h10
2 files changed, 15 insertions, 1 deletions
diff --git a/executor/executor_runner.h b/executor/executor_runner.h
index 57d63f6a7..766669dda 100644
--- a/executor/executor_runner.h
+++ b/executor/executor_runner.h
@@ -797,5 +797,11 @@ static void runner(char** argv, int argc)
fail("signal(SIGBUS) failed");
Connection conn(manager_addr, manager_port);
+
+ // This is required to make Subprocess fd remapping logic work.
+ // kCoverFilterFd is the largest fd we set in the child processes.
+ for (int fd = conn.FD(); fd < kCoverFilterFd;)
+ fd = dup(fd);
+
Runner(conn, name, argv[0]);
}
diff --git a/executor/subprocess.h b/executor/subprocess.h
index 4477cc482..2553422a9 100644
--- a/executor/subprocess.h
+++ b/executor/subprocess.h
@@ -17,9 +17,17 @@ public:
if (posix_spawn_file_actions_init(&actions))
fail("posix_spawn_file_actions_init failed");
int max_fd = 0;
- for (auto pair : fds) {
+ for (auto pair : fds)
max_fd = std::max(max_fd, pair.second);
+ for (auto pair : fds) {
if (pair.first != -1) {
+ // Remapping won't work if fd's overlap with the target range:
+ // we can dup something onto fd we need to dup later, in such case the later fd
+ // will be wrong. Resolving this would require some tricky multi-pass remapping.
+ // So we just require the caller to not do that.
+ if (pair.first <= max_fd)
+ failmsg("bad subprocess fd", "%d->%d max_fd=%d",
+ pair.first, pair.second, max_fd);
if (posix_spawn_file_actions_adddup2(&actions, pair.first, pair.second))
fail("posix_spawn_file_actions_adddup2 failed");
} else {