diff options
author | eldritch horrors <pennae@lix.systems> | 2024-04-05 22:22:44 +0200 |
---|---|---|
committer | eldritch horrors <pennae@lix.systems> | 2024-07-05 22:28:16 +0000 |
commit | b6a08a2fed8a48d3759ea67e958c9f9ec5f44d94 (patch) | |
tree | 7cfdefa2d8c354a77f9d8977ad33efbc1766ed33 /src/libutil/processes.cc | |
parent | f4f6d1d8e24a092422fcec601e21683179b735c9 (diff) |
libutil: return a program handle from runProgram2
this will let us also return a source for the program output later,
which will in turn make sinkToSource unnecessary for program output
processing. this may also reopen a path for provigin program input,
but that still needs a proper async io framework to avoid problems.
Change-Id: Iaf93f47db99c38cfaf134bd60ed6a804d7ddf688
Diffstat (limited to 'src/libutil/processes.cc')
-rw-r--r-- | src/libutil/processes.cc | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/src/libutil/processes.cc b/src/libutil/processes.cc index bd5ccdb4b..3c353d82e 100644 --- a/src/libutil/processes.cc +++ b/src/libutil/processes.cc @@ -249,7 +249,7 @@ std::pair<int, std::string> runProgram(RunOptions && options) int status = 0; try { - runProgram2(options); + runProgram2(options).wait(); } catch (ExecError & e) { status = e.status; } @@ -257,7 +257,25 @@ std::pair<int, std::string> runProgram(RunOptions && options) return {status, std::move(sink.s)}; } -void runProgram2(const RunOptions & options) +RunningProgram::~RunningProgram() +{ + if (pid) { + // we will not kill a subprocess because we *can't* kill a subprocess + // reliably without placing it in its own process group, and cleaning + // up a subprocess only when `separatePG` is set is a loaded footgun. + assert(false && "destroying un-wait()ed running process"); + std::terminate(); + } +} + +void RunningProgram::wait() +{ + int status = pid.wait(); + if (status) + throw ExecError(status, "program '%1%' %2%", program, statusToString(status)); +} + +RunningProgram runProgram2(const RunOptions & options) { checkInterrupt(); @@ -317,11 +335,7 @@ void runProgram2(const RunOptions & options) if (options.standardOut) *options.standardOut << drainFDSource(out.readSide.get()); - /* Wait for the child to finish. */ - int status = pid.wait(); - - if (status) - throw ExecError(status, "program '%1%' %2%", options.program, statusToString(status)); + return RunningProgram{options.program, std::move(pid)}; } std::string statusToString(int status) |