libutil/runProgram2: support posix_spawn-like dup-to-self redirections

posix_spawn unsets CLOEXEC for fds that are dup'd onto their existing fd
number. this is very useful when inheriting fd numbers exceeding stderr.

Change-Id: I6f14585d424ded6741fdd087f0c4d33a05936bcc
This commit is contained in:
eldritch horrors
2025-07-04 14:01:11 +02:00
parent 0f0718422f
commit 164d23f38d
+8 -1
View File
@@ -10,6 +10,7 @@
#include <cerrno>
#include <cstdlib>
#include <cstring>
#include <fcntl.h>
#include <iostream>
#include <grp.h>
@@ -332,7 +333,13 @@ RunningProgram runProgram2(const RunOptions & options)
if (options.captureStdout && dup2(out.writeSide.get(), STDOUT_FILENO) == -1)
throw SysError("dupping stdout");
for (auto redirection : options.redirections) {
if (dup2(redirection.from, redirection.dup) == -1) {
if (redirection.dup == redirection.from) {
if (int flags = fcntl(redirection.from, F_GETFD);
flags < 0 || fcntl(redirection.from, F_SETFD, flags & ~FD_CLOEXEC) < 0)
{
throw SysError("clearing O_CLOEXEC of fd %i", redirection.dup);
}
} else if (dup2(redirection.from, redirection.dup) == -1) {
throw SysError("dupping fd %i to %i", redirection.dup, redirection.from);
}
}