diff --git a/lix/libfetchers/git.cc b/lix/libfetchers/git.cc index 3231ec011..aa3ef7150 100644 --- a/lix/libfetchers/git.cc +++ b/lix/libfetchers/git.cc @@ -22,6 +22,7 @@ #include #include #include +#include using namespace std::string_literals; @@ -164,11 +165,19 @@ WorkdirInfo getWorkdirInfo(const Input & input, const Path & workdir) /* Check whether HEAD points to something that looks like a commit, since that is the refrence we want to use later on. */ - auto result = runProgram(RunOptions { + auto result = runProgram(RunOptions{ .program = "git", - .args = { "-C", workdir, "--git-dir", gitDir, "rev-parse", "--verify", "--no-revs", "HEAD^{commit}" }, + .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; @@ -709,10 +718,12 @@ struct GitInputScheme : InputScheme AutoDelete delTmpDir(tmpDir, true); PathFilter filter = defaultPathFilter; - auto result = runProgram(RunOptions { + auto result = runProgram(RunOptions{ .program = "git", - .args = { "-C", repoDir, "--git-dir", gitDir, "cat-file", "commit", input.getRev()->gitRev() }, - .mergeStderrToStdout = true + .args = + {"-C", repoDir, "--git-dir", gitDir, "cat-file", "commit", input.getRev()->gitRev() + }, + .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 69e654490..48d38ffb4 100644 --- a/lix/libstore/build/derivation-goal.cc +++ b/lix/libstore/build/derivation-goal.cc @@ -891,7 +891,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..b4328b068 100644 --- a/lix/libstore/globals.cc +++ b/lix/libstore/globals.cc @@ -242,9 +242,17 @@ StringSet Settings::getDefaultExtraPlatforms() // machines. Note that we can’t force processes from executing // 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) + if (std::string{SYSTEM} == "aarch64-darwin" + && 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 return extraPlatforms; diff --git a/lix/libstore/ssh.cc b/lix/libstore/ssh.cc index b43cc50a9..2b329f231 100644 --- a/lix/libstore/ssh.cc +++ b/lix/libstore/ssh.cc @@ -8,6 +8,7 @@ #include "lix/libutil/strings.hh" #include "lix/libstore/temporary-dir.hh" #include +#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