From 8e4b4c62f5bd33bbddcd335fc54e377a5fd4f8c8 Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Mon, 17 Mar 2025 15:45:27 +0100 Subject: [PATCH] libutil: add generic redirections runProgram2 explicit stderr redirection makes mergeStderrToStdout unnecessary also. Change-Id: I63de929e6dc53f6c5ceb2d43c2ce288bfc04d872 --- lix/libfetchers/git.cc | 5 +++-- lix/libstore/build/derivation-goal.cc | 2 +- lix/libstore/globals.cc | 6 +++++- lix/libstore/ssh.cc | 1 + lix/libutil/processes.cc | 8 +++++--- lix/libutil/processes.hh | 7 ++++++- 6 files changed, 21 insertions(+), 8 deletions(-) diff --git a/lix/libfetchers/git.cc b/lix/libfetchers/git.cc index 462be82ab..4ce38c1a8 100644 --- a/lix/libfetchers/git.cc +++ b/lix/libfetchers/git.cc @@ -22,6 +22,7 @@ #include #include #include +#include using namespace std::string_literals; @@ -168,7 +169,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; @@ -701,7 +702,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) diff --git a/lix/libstore/build/derivation-goal.cc b/lix/libstore/build/derivation-goal.cc index c6c971709..e75e5fb5c 100644 --- a/lix/libstore/build/derivation-goal.cc +++ b/lix/libstore/build/derivation-goal.cc @@ -1011,7 +1011,7 @@ void runPostBuildHook( .program = settings.postBuildHook, .environment = hookEnvironment, .captureStdout = true, - .mergeStderrToStdout = true, + .redirections = {{.from = STDERR_FILENO, .to = STDOUT_FILENO}}, }); Finally const _wait([&] { try { diff --git a/lix/libstore/globals.cc b/lix/libstore/globals.cc index 9221da32b..4ae324172 100644 --- a/lix/libstore/globals.cc +++ b/lix/libstore/globals.cc @@ -243,7 +243,11 @@ 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 diff --git a/lix/libstore/ssh.cc b/lix/libstore/ssh.cc index 06ad66bc3..1309029e8 100644 --- a/lix/libstore/ssh.cc +++ b/lix/libstore/ssh.cc @@ -5,6 +5,7 @@ #include "lix/libutil/logging.hh" #include "lix/libutil/strings.hh" #include "lix/libstore/temporary-dir.hh" +#include namespace nix { diff --git a/lix/libutil/processes.cc b/lix/libutil/processes.cc index 6b24d943f..0dcd96ba9 100644 --- a/lix/libutil/processes.cc +++ b/lix/libutil/processes.cc @@ -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"); diff --git a/lix/libutil/processes.hh b/lix/libutil/processes.hh index 01c42b9fc..3311b8fb8 100644 --- a/lix/libutil/processes.hh +++ b/lix/libutil/processes.hh @@ -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 chdir = {}; std::optional> environment = {}; bool captureStdout = false; - bool mergeStderrToStdout = false; bool isInteractive = false; + std::vector redirections; }; struct [[nodiscard("you must call RunningProgram::wait()")]] RunningProgram