pub struct OwnedChild { /* private fields */ }Expand description
One exclusively owned child, normally spawned as a new process-group leader.
Self::spawn preserves the command’s IO, environment and other settings,
replacing its process-group selection with a new group. It performs no
executable admission. The child must not change groups, and callers must
not independently reap it (including through a global SIGCHLD handler).
Ordinary waiting signals remaining group members before reaping the leader.
For a deliberate background handoff, Self::poll_exit observes without
releasing cleanup ownership, then Self::handoff reaps a successful leader
without signalling its group. The caller then owns the background lifetime.
Drop makes a best-effort kill/reap attempt, including during unwinding. Use
Self::terminate to observe cleanup failures. The default cleanup waits
synchronously; Self::spawn_with_cleanup can select bounded reaping.
Successful signalling is not proof that descendants
have exited or completed external effects. Only the direct child is reaped.
Group signalling can succeed for only some members when credentials differ.
Implementations§
Source§impl OwnedChild
impl OwnedChild
Sourcepub fn spawn(command: &mut Command) -> Result<Self>
pub fn spawn(command: &mut Command) -> Result<Self>
Spawn once in a new owned process group, preserving caller-configured IO.
§Errors
Returns the native spawn/setup failure. No retries are performed.
Sourcepub fn spawn_with_cleanup(
command: &mut Command,
cleanup: CleanupPolicy,
) -> Result<Self>
pub fn spawn_with_cleanup( command: &mut Command, cleanup: CleanupPolicy, ) -> Result<Self>
Spawn a new owned group with caller-selected termination timing.
The policy applies whenever termination is needed, including communication failures and Drop during unwinding. It does not change natural waiting or successful background handoff. No signal handler or reaper thread is added.
use ic_host_process::child::{CleanupPolicy, OwnedChild};
use std::{process::Command, time::Duration};
let mut child = OwnedChild::spawn_with_cleanup(
&mut Command::new("caller-selected-tool"),
CleanupPolicy::TermThenKill {
grace: Duration::from_secs(5),
reap_timeout: Duration::from_secs(5),
},
)?;
// Configure command IO before spawn; communicate/admit before handoff.
child.terminate()?;§Errors
Returns the native spawn/setup failure. No retries are performed.
Sourcepub fn id(&self) -> u32
pub fn id(&self) -> u32
Direct-child PID, for observation only; it can be reused after reaping.
Sourcepub const fn take_stdin(&mut self) -> Option<ChildStdin>
pub const fn take_stdin(&mut self) -> Option<ChildStdin>
Take caller-configured piped stdin. Close it before waiting for EOF-driven children.
Sourcepub const fn take_stdout(&mut self) -> Option<ChildStdout>
pub const fn take_stdout(&mut self) -> Option<ChildStdout>
Take caller-configured piped stdout; the caller owns draining and bounds.
Sourcepub const fn take_stderr(&mut self) -> Option<ChildStderr>
pub const fn take_stderr(&mut self) -> Option<ChildStderr>
Take caller-configured piped stderr; the caller owns draining and bounds.
Sourcepub fn poll_exit(&mut self) -> Result<Option<ExitStatus>>
pub fn poll_exit(&mut self) -> Result<Option<ExitStatus>>
Observe leader exit without signalling or reaping it.
An exited leader stays reserved with WNOWAIT, so cancellation, failed IO
admission and unwinding still clean its group. Repeated observations do
not release ownership. After a completed wait/termination/handoff, returns
the cached status. This status alone does not establish a handoff.
Call Self::handoff only after admitting a successful background start.
Otherwise use Self::wait or Self::terminate to clean and reap.
§Errors
Returns native inspection errors; external reaping invalidates ownership.
Sourcepub fn handoff(&mut self) -> Result<ExitStatus>
pub fn handoff(&mut self) -> Result<ExitStatus>
Reap an already successful leader without signalling its remaining group.
This is the explicit transfer point for a background lifetime. The caller must first admit its IO/result and arrange application-owned readiness, cancellation and stop/recovery. Zero exit does not prove those obligations. No PID/group handle is transferred: it could be reused after reaping. Subsequent wait/termination/Drop never signal the handed-off group.
Use Self::poll_exit while draining IO and checking cancellation. A
running or unsuccessful leader is refused without releasing ownership;
use ordinary wait/termination for failed startup, keeping its original
failure separate from any cleanup error. Drop still attempts cleanup.
§Errors
Returns InvalidInput for a running, unsuccessful, terminating or already-reaped
leader, or native inspection/reap errors. Reap failures retain cleanup
ownership unless it was lost externally.
Sourcepub fn try_wait(&mut self) -> Result<Option<ExitStatus>>
pub fn try_wait(&mut self) -> Result<Option<ExitStatus>>
Inspect exit without blocking on a running child; clean its group before reaping.
Repeated successful calls return the cached status without signalling again.
§Errors
Returns native inspection, group-signal or reap errors. The leader remains reserved on a group-signal failure, so explicit cleanup can still be attempted.
Sourcepub fn wait(&mut self) -> Result<ExitStatus>
pub fn wait(&mut self) -> Result<ExitStatus>
Wait for natural leader exit, then clean its group and reap the leader.
Close/drain caller-owned pipes as needed before waiting. No deadline or cancellation policy is installed; callers may use polling instead.
§Errors
Returns native inspection, group-signal or reap errors.
Sourcepub fn terminate(&mut self) -> Result<ExitStatus, CleanupError>
pub fn terminate(&mut self) -> Result<ExitStatus, CleanupError>
Terminate the owned group (or internal direct child), then reap the leader.
Repeated calls after reaping return the cached status and never signal a
reused PID. A prior group failure still matters even if reaping succeeded;
later calls cannot recover group ownership and do not erase that evidence.
With CleanupPolicy::TermThenKill, successful TERM signalling is followed
by the full grace period without reaping, then KILL even if the leader has
exited. A TERM error does not prevent KILL or reaping. The reap allowance
begins after signalling; repeated termination and Drop never restart it or
repeat escalation. Reap timeout returns TimedOut in wait_error while
keeping the unreaped child owned. Callers may explicitly recover with
try_wait/wait; dropping after timeout can leave an unreaped child until
parent exit. No background reaper is installed. Scheduling and native
syscall latency are outside these polling bounds.
§Errors
Retains each failed cleanup step separately. Group failure triggers a direct-child kill fallback. Drop cannot report errors; call this explicitly when cleanup evidence matters.