aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/processes.cc
diff options
context:
space:
mode:
authoreldritch horrors <pennae@lix.systems>2024-04-05 23:02:11 +0200
committereldritch horrors <pennae@lix.systems>2024-07-06 12:36:36 +0200
commit4162a66cee97ec16c88d991ef9a6d9baa3740053 (patch)
tree41bcdefb5d85c9c26be3563a3880bc850f41bec3 /src/libutil/processes.cc
parentb6a08a2fed8a48d3759ea67e958c9f9ec5f44d94 (diff)
libutil: return sources from runProgram2
this much more closely mimics what is actually happening: we're reading data from somewhere else, actively, rather than passively waiting. with the data flow matching the underlying system interactions better we can remove a few sinkToSource calls that merely exists to undo the mismatch caused by not treating subprocess output as a data source to begin with Change-Id: If4abfc2f8398fb5e88c9b91a8bdefd5504bb2d11
Diffstat (limited to 'src/libutil/processes.cc')
-rw-r--r--src/libutil/processes.cc31
1 files changed, 21 insertions, 10 deletions
diff --git a/src/libutil/processes.cc b/src/libutil/processes.cc
index 3c353d82e..4fe3dcfb4 100644
--- a/src/libutil/processes.cc
+++ b/src/libutil/processes.cc
@@ -243,18 +243,28 @@ std::string runProgram(Path program, bool searchPath, const Strings & args, bool
// Output = error code + "standard out" output stream
std::pair<int, std::string> runProgram(RunOptions && options)
{
- StringSink sink;
- options.standardOut = &sink;
+ options.captureStdout = true;
int status = 0;
+ std::string stdout;
try {
- runProgram2(options).wait();
+ auto proc = runProgram2(options);
+ Finally const _wait([&] { proc.wait(); });
+ stdout = proc.stdout()->drain();
} catch (ExecError & e) {
status = e.status;
}
- return {status, std::move(sink.s)};
+ return {status, std::move(stdout)};
+}
+
+RunningProgram::RunningProgram(PathView program, Pid pid, AutoCloseFD stdout)
+ : program(program)
+ , pid(std::move(pid))
+ , stdoutSource(stdout ? std::make_unique<FdSource>(stdout.get()) : nullptr)
+ , stdout_(std::move(stdout))
+{
}
RunningProgram::~RunningProgram()
@@ -281,7 +291,7 @@ RunningProgram runProgram2(const RunOptions & options)
/* Create a pipe. */
Pipe out;
- if (options.standardOut) out.create();
+ if (options.captureStdout) out.create();
ProcessOptions processOptions;
@@ -299,7 +309,7 @@ RunningProgram runProgram2(const RunOptions & options)
Pid pid{startProcess([&]() {
if (options.environment)
replaceEnv(*options.environment);
- if (options.standardOut && dup2(out.writeSide.get(), STDOUT_FILENO) == -1)
+ if (options.captureStdout && dup2(out.writeSide.get(), STDOUT_FILENO) == -1)
throw SysError("dupping stdout");
if (options.mergeStderrToStdout)
if (dup2(STDOUT_FILENO, STDERR_FILENO) == -1)
@@ -332,10 +342,11 @@ RunningProgram runProgram2(const RunOptions & options)
out.writeSide.close();
- if (options.standardOut)
- *options.standardOut << drainFDSource(out.readSide.get());
-
- return RunningProgram{options.program, std::move(pid)};
+ return RunningProgram{
+ options.program,
+ std::move(pid),
+ options.captureStdout ? std::move(out.readSide) : AutoCloseFD{}
+ };
}
std::string statusToString(int status)