aboutsummaryrefslogtreecommitdiffstats
path: root/executor/subprocess.h
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2024-06-28 13:20:29 +0200
committerDmitry Vyukov <dvyukov@google.com>2024-06-28 12:16:25 +0000
commit2081f66ad07722ba9a808fa4f0d2ced2822950f7 (patch)
tree4c2f74ff1ee6ba546efbb9dd98f416ed2760cf44 /executor/subprocess.h
parent30bd3f741301a9ad137b62a686ba1ed2284388c8 (diff)
executor: fix max signal/cover filter mapping into subprocesses
There is a quirk related to posix_spawn_file_actions_adddup2: it just executes the specified dup's in order in the child process. In our case we do dups as follows: 20 -> 4 (output region) 4 -> 5 (max signal) So we dup the output region onto 4 first, and then dup the same output region (fd 4 becomes the output region) onto 5 (max signal). So we have output region as both output region and max signal.
Diffstat (limited to 'executor/subprocess.h')
-rw-r--r--executor/subprocess.h10
1 files changed, 9 insertions, 1 deletions
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 {