Skip to main content

ContainedChild

Struct ContainedChild 

Source
pub struct ContainedChild { /* private fields */ }
Expand description

A spawned child leading its own process group, with tree-wide termination.

While the leader is unreaped and the handle is armed, dropping it SIGKILLs the group — the containment guarantee under task abort. Once reaped, the guard stands down: the id is no longer safely ours to signal.

Implementations§

Source§

impl ContainedChild

Source

pub fn spawn(command: Command) -> Result<Self, ProcessGroupError>

Spawn command as the leader of a fresh process group.

The caller configures stdio before calling: piping it captures output, inheriting it sends the child’s output wherever this process’s goes.

§Errors

Returns ProcessGroupError::Unsupported on a target without process groups, ProcessGroupError::Spawn when the command cannot start, and ProcessGroupError::MissingProcessId or ProcessGroupError::ProcessIdOutOfRange when the started child cannot be addressed as a group.

Source

pub fn id(&self) -> Option<u32>

The direct child’s process id, while it has not been reaped.

Source

pub const fn process_group_id(&self) -> Option<i32>

The raw process-group id, on a target that has process groups.

None off Unix, where Self::spawn refuses in the first place.

Source

pub const fn exit_status(&self) -> Option<ExitStatus>

The exit status recorded by whichever call reaped the leading child.

Source

pub fn take_stdout(&mut self) -> Option<ChildStdout>

Take the captured stdout pipe, when the command was configured with one.

Source

pub fn take_stderr(&mut self) -> Option<ChildStderr>

Take the captured stderr pipe, when the command was configured with one.

Source

pub async fn wait(&mut self) -> Result<ExitStatus, ProcessGroupError>

Wait for the DIRECT child to exit, REAPING it.

After this returns, the process-group id is no longer safely ours: see the module header. Callers that still need to stop the tree must use [Self::wait_for_exit] instead, which observes the exit without consuming it.

§Errors

Returns ProcessGroupError::Reap when waiting fails.

Source

pub async fn terminate( &mut self, grace: Duration, ) -> Result<(), ProcessGroupError>

Stop the whole group, then reap the leading child.

SIGTERMgraceSIGKILL, BOTH sent while the leader is unreaped, so the group being signalled is provably the one this handle created. Once the leader has already been reaped no signal is sent at all: the id may belong to anyone by then, and a stop that cannot be aimed is a stop that must not be attempted.

The SIGKILL is unconditional rather than conditional on surviving the SIGTERM. Checking first would mean either reaping the leader (which forfeits the right to signal) or reading a probe that a live-or-zombie leader always answers “alive” to — so the check cannot work, and an extra signal to an empty group costs nothing.

This says nothing about whether the group ended up EMPTY. Proving that is the caller’s job: Self::confirm_group_gone where there is nothing else to go on, or end-of-file on captured output, which no surviving descendant holding the write end could produce.

§Errors

Returns ProcessGroupError::Unsupported off Unix, ProcessGroupError::Signal when the OS refuses to signal, and ProcessGroupError::Reap when the leader cannot be reaped.

Source

pub async fn confirm_group_gone( &self, within: Duration, ) -> Result<(), ProcessGroupError>

Poll until the group is provably gone, or the window closes.

A read, never an act — which is what makes it safe after the leader has been reaped, where acting on a wrong answer would be the disaster.

§Errors

Returns ProcessGroupError::Unsupported off Unix, ProcessGroupError::Probe when the probe itself fails, and ProcessGroupError::GroupStillAlive when the window closes with the group still observable.

Source

pub const fn disarm(&mut self)

Release the drop guard without signalling anything.

For a caller that has established the group is gone by other means — the captured pipes reaching EOF, for instance, which no descendant holding the write end could allow.

Trait Implementations§

Source§

impl Debug for ContainedChild

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Drop for ContainedChild

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<L> LayerExt<L> for L

Source§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more