libutil: add generic redirections runProgram2
explicit stderr redirection makes mergeStderrToStdout unnecessary also. Change-Id: I63de929e6dc53f6c5ceb2d43c2ce288bfc04d872
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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(); });
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user