Merge nucleic/sleek-thistle-egret-fyej into dev

This commit is contained in:
2026-07-18 12:45:36 -07:00
parent 5648b96ddc
commit 26fd468ad0
6 changed files with 208 additions and 6 deletions
+42 -3
View File
@@ -17,6 +17,9 @@ pub struct ChildProcess {
pid: Option<sys::process::ProcessId>,
/// If available, the process group ID of the child.
pgid: Option<sys::process::ProcessId>,
// nash: gate token issued by `Gate::on_exec` for this command, reported
// back via `Gate::on_exit` when the process completes.
pub(crate) gate_token: Option<u64>,
}
impl ChildProcess {
@@ -30,6 +33,7 @@ impl ChildProcess {
exec_future: Box::pin(child.wait_with_output()),
pid,
pgid,
gate_token: None,
}
}
@@ -54,7 +58,15 @@ impl ChildProcess {
loop {
tokio::select! {
output = &mut self.exec_future => {
break Ok(ProcessWaitResult::Completed(output?))
let output = output?;
// nash: report process completion to the gate exactly once.
if let Some(token) = self.gate_token.take() {
crate::gate::gate().on_exit(
token,
crate::gate::ExecEnd { exit_code: exit_code_of(&output.status) },
);
}
break Ok(ProcessWaitResult::Completed(output))
},
_ = sigtstp.recv() => {
break Ok(ProcessWaitResult::Stopped)
@@ -75,12 +87,39 @@ impl ChildProcess {
pub(crate) fn poll(&mut self) -> Option<Result<std::process::Output, error::Error>> {
let checkable_future = &mut self.exec_future;
checkable_future
let result: Option<Result<std::process::Output, error::Error>> = checkable_future
.now_or_never()
.map(|result| result.map_err(Into::into))
.map(|result| result.map_err(Into::into));
// nash: completion can also be observed via poll (e.g. job checks).
if let Some(Ok(output)) = &result {
if let Some(token) = self.gate_token.take() {
crate::gate::gate().on_exit(
token,
crate::gate::ExecEnd {
exit_code: exit_code_of(&output.status),
},
);
}
}
result
}
}
// nash: numeric exit code for gate reporting (128+signal for signal deaths).
fn exit_code_of(status: &std::process::ExitStatus) -> i32 {
if let Some(code) = status.code() {
return code;
}
#[cfg(unix)]
{
use std::os::unix::process::ExitStatusExt;
if let Some(signal) = status.signal() {
return 128 + signal;
}
}
1
}
/// Represents the result of waiting for an executing process.
pub enum ProcessWaitResult {
/// The process completed.