libutil: add generic redirections runProgram2

explicit stderr redirection makes mergeStderrToStdout unnecessary also.

Change-Id: I63de929e6dc53f6c5ceb2d43c2ce288bfc04d872
This commit is contained in:
eldritch horrors
2025-06-24 10:50:36 +00:00
parent d0678a57f9
commit 0ea8649445
6 changed files with 20 additions and 9 deletions
+3 -2
View File
@@ -20,6 +20,7 @@
#include <string.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <unistd.h>
using namespace std::string_literals;
@@ -166,7 +167,7 @@ WorkdirInfo getWorkdirInfo(const Input & input, const Path & workdir)
.program = "git",
.args = { "-C", workdir, "--git-dir", gitDir, "rev-parse", "--verify", "--no-revs", "HEAD^{commit}" },
.environment = env,
.mergeStderrToStdout = true
.redirections = {{.from = STDERR_FILENO, .to = STDOUT_FILENO}},
});
auto exitCode = WEXITSTATUS(result.first);
auto errorMessage = result.second;
@@ -694,7 +695,7 @@ struct GitInputScheme : InputScheme
auto result = runProgram(RunOptions {
.program = "git",
.args = { "-C", repoDir, "--git-dir", gitDir, "cat-file", "commit", input.getRev()->gitRev() },
.mergeStderrToStdout = true
.redirections = {{.from = STDERR_FILENO, .to = STDOUT_FILENO}},
});
if (WEXITSTATUS(result.first) == 128
&& result.second.find("bad file") != std::string::npos)
+1 -1
View File
@@ -988,7 +988,7 @@ void runPostBuildHook(
.program = settings.postBuildHook,
.environment = hookEnvironment,
.captureStdout = true,
.mergeStderrToStdout = true,
.redirections = {{.from = STDERR_FILENO, .to = STDOUT_FILENO}},
});
Finally const _wait([&] { proc.waitAndCheck(); });
+2 -1
View File
@@ -244,7 +244,8 @@ StringSet Settings::getDefaultExtraPlatforms()
// x86_64 in aarch64 environments or vice versa since they can
// always exec with their own binary preferences.
if (std::string{SYSTEM} == "aarch64-darwin" &&
runProgram(RunOptions {.program = "arch", .args = {"-arch", "x86_64", "/usr/bin/true"}, .mergeStderrToStdout = true}).first == 0)
runProgram(RunOptions {.program = "arch", .args = {"-arch", "x86_64", "/usr/bin/true"},
.redirections = {{.from = STDERR_FILENO, .to = STDOUT_FILENO}}}).first == 0)
extraPlatforms.insert("x86_64-darwin");
#endif
+3 -1
View File
@@ -5,6 +5,7 @@
#include "lix/libutil/logging.hh"
#include "lix/libutil/strings.hh"
#include "lix/libstore/temporary-dir.hh"
#include <unistd.h>
namespace nix {
@@ -50,7 +51,8 @@ bool SSHMaster::isMasterRunning() {
Strings args = {"-O", "check", host};
addCommonSSHOpts(args);
auto res = runProgram(RunOptions {.program = "ssh", .args = args, .mergeStderrToStdout = true});
auto res = runProgram(RunOptions {.program = "ssh", .args = args,
.redirections = {{.from = STDERR_FILENO, .to = STDOUT_FILENO}}});
return res.first == 0;
}
+5 -3
View File
@@ -330,9 +330,11 @@ RunningProgram runProgram2(const RunOptions & options)
replaceEnv(*options.environment);
if (options.captureStdout && dup2(out.writeSide.get(), STDOUT_FILENO) == -1)
throw SysError("dupping stdout");
if (options.mergeStderrToStdout)
if (dup2(STDOUT_FILENO, STDERR_FILENO) == -1)
throw SysError("cannot dup stdout into stderr");
for (auto redirection : options.redirections) {
if (dup2(redirection.to, redirection.from) == -1) {
throw SysError("dupping fd %i to %i", redirection.from, redirection.to);
}
}
if (options.chdir && chdir((*options.chdir).c_str()) == -1)
throw SysError("chdir failed");
+6 -1
View File
@@ -76,6 +76,11 @@ std::string runProgram(Path program, bool searchPath = false,
struct RunOptions
{
struct Redirection
{
int from, to;
};
Path program;
bool searchPath = true;
Strings args = {};
@@ -84,8 +89,8 @@ struct RunOptions
std::optional<Path> chdir = {};
std::optional<std::map<std::string, std::string>> environment = {};
bool captureStdout = false;
bool mergeStderrToStdout = false;
bool isInteractive = false;
std::vector<Redirection> redirections;
};
struct [[nodiscard("you must call RunningProgram::wait()")]] RunningProgram