ProcessHandle

Struct ProcessHandle 

Source
pub struct ProcessHandle<O: OutputStream> { /* private fields */ }
Expand description

A handle to a spawned process with captured stdout/stderr streams.

This type provides methods for waiting on process completion, terminating the process, and accessing its output streams. By default, processes must be explicitly waited on or terminated before being dropped (see ProcessHandle::must_be_terminated).

If applicable, a process handle can be wrapped in a TerminateOnDrop to be terminated automatically upon being dropped. Note that this requires a multi-threaded runtime!

Implementations§

Source§

impl ProcessHandle<BroadcastOutputStream>

Source

pub async fn wait_for_completion_with_output( &mut self, timeout: Option<Duration>, options: LineParsingOptions, ) -> Result<Output, WaitError>

Convenience function, waiting for the process to complete using ProcessHandle::wait_for_completion while collecting both stdout and stderr into individual Vec<String> collections using the provided LineParsingOptions.

You may want to destructure this using:

let Output {
    status,
    stdout,
    stderr
} = proc.wait_for_completion_with_output(None, LineParsingOptions::default()).await.unwrap();
Source

pub async fn wait_for_completion_with_output_or_terminate( &mut self, wait_timeout: Duration, interrupt_timeout: Duration, terminate_timeout: Duration, options: LineParsingOptions, ) -> Result<Output, WaitError>

Convenience function, waiting for the process to complete using ProcessHandle::wait_for_completion_or_terminate while collecting both stdout and stderr into individual Vec<String> collections using the provided LineParsingOptions.

Source§

impl ProcessHandle<SingleSubscriberOutputStream>

Source

pub async fn wait_for_completion_with_output( &mut self, timeout: Option<Duration>, options: LineParsingOptions, ) -> Result<Output, WaitError>

Convenience function, waiting for the process to complete using ProcessHandle::wait_for_completion while collecting both stdout and stderr into individual Vec<String> collections using the provided LineParsingOptions.

You may want to destructure this using:

let Output {
    status,
    stdout,
    stderr
} = proc.wait_for_completion_with_output(None, LineParsingOptions::default()).await.unwrap();
Source

pub async fn wait_for_completion_with_output_or_terminate( &mut self, wait_timeout: Duration, interrupt_timeout: Duration, terminate_timeout: Duration, options: LineParsingOptions, ) -> Result<Output, WaitError>

Convenience function, waiting for the process to complete using ProcessHandle::wait_for_completion_or_terminate while collecting both stdout and stderr into individual Vec<String> collections using the provided LineParsingOptions.

Source§

impl<O: OutputStream> ProcessHandle<O>

Source

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

Returns the OS process ID if the process hasn’t exited yet.

Once this process has been polled to completion this will return None.

Source

pub fn is_running(&mut self) -> RunningState

Checks if the process is currently running.

Returns RunningState::Running if the process is still running, RunningState::Terminated if it has exited, or RunningState::Uncertain if the state could not be determined.

Source

pub fn stdin(&mut self) -> &mut Stdin

Returns a mutable reference to the (potentially already closed) stdin stream.

Use this to write data to the child process’s stdin. The stdin stream implements tokio::io::AsyncWrite, allowing you to use methods like write_all() and flush().

§Example
// Whether we `spawn_broadcast` or `spawn_single_subscriber` does not make a difference here.
let mut process = Process::new(Command::new("cat"))
    .spawn_broadcast()
    .unwrap();

// Write to stdin.
if let Some(stdin) = process.stdin().as_mut() {
    stdin.write_all(b"Hello, process!\n").await.unwrap();
    stdin.flush().await.unwrap();
}

// Close stdin to signal EOF.
process.stdin().close();
Source

pub fn stdout(&self) -> &O

Returns a reference to the stdout stream.

For BroadcastOutputStream, this allows creating multiple concurrent consumers. For SingleSubscriberOutputStream, only one consumer can be created (subsequent attempts will panic with a helpful error message).

Source

pub fn stderr(&self) -> &O

Returns a reference to the stderr stream.

For BroadcastOutputStream, this allows creating multiple concurrent consumers. For SingleSubscriberOutputStream, only one consumer can be created (subsequent attempts will panic with a helpful error message).

Source

pub fn must_be_terminated(&mut self)

Sets a panic-on-drop mechanism for this ProcessHandle.

This method enables a safeguard that ensures that the process represented by this ProcessHandle is properly terminated or awaited before being dropped. If must_be_terminated is set and the ProcessHandle is dropped without invoking terminate() or wait(), an intentional panic will occur to prevent silent failure-states, ensuring that system resources are handled correctly.

You typically do not need to call this, as every ProcessHandle is marked by default. Call must_not_be_terminated to clear this safeguard to explicitly allow dropping the process without terminating it.

§Panic

If the ProcessHandle is dropped without being awaited or terminated after calling this method, a panic will occur with a descriptive message to inform about the incorrect usage.

Source

pub fn must_not_be_terminated(&mut self)

Disables the panic-on-drop safeguard, allowing the spawned process to be kept running uncontrolled in the background, while this handle can safely be dropped.

Source

pub fn terminate_on_drop( self, graceful_termination_timeout: Duration, forceful_termination_timeout: Duration, ) -> TerminateOnDrop<O>

Wrap this process handle in a TerminateOnDrop instance, terminating the controlled process automatically when this handle is dropped.

SAFETY: This only works when your code is running in a multithreaded tokio runtime!

Prefer manual termination of the process or awaiting it and relying on the (automatically configured) must_be_terminated logic, raising a panic when a process was neither awaited nor terminated before being dropped.

Source

pub fn send_interrupt_signal(&mut self) -> Result<(), Error>

Manually send a SIGINT on unix or equivalent on Windows to this process.

Prefer to call terminate instead, if you want to make sure this process is terminated.

Source

pub fn send_terminate_signal(&mut self) -> Result<(), Error>

Manually send a SIGTERM on unix or equivalent on Windows to this process.

Prefer to call terminate instead, if you want to make sure this process is terminated.

Source

pub async fn terminate( &mut self, interrupt_timeout: Duration, terminate_timeout: Duration, ) -> Result<ExitStatus, TerminationError>

Terminates this process by sending a SIGINT, SIGTERM or even a SIGKILL if the process doesn’t run to completion after receiving any of the first two signals.

This handle can be dropped safely after this call returned, no matter the outcome. We accept that in extremely rare cases, failed SIGKILL, a rogue process may be left over.

Source

pub async fn kill(&mut self) -> Result<()>

Forces the process to exit. Most users should call ProcessHandle::terminate instead.

This is equivalent to sending a SIGKILL on unix platforms followed by wait.

Source

pub async fn wait_for_completion( &mut self, timeout: Option<Duration>, ) -> Result<ExitStatus, WaitError>

Wait for this process to run to completion. Within timeout, if set, or unbound otherwise.

If the timeout is reached before the process terminated, an error is returned but the process remains untouched / keeps running. Use ProcessHandle::wait_for_completion_or_terminate if you want immediate termination.

This does not provide the processes output. You can take a look at the convenience function ProcessHandle::::wait_for_completion_with_output to see how the ProcessHandle::stdout and ProcessHandle::stderr streams (also available in *_mut variants) can be used to inspect / watch over / capture the processes output.

Source

pub async fn wait_for_completion_or_terminate( &mut self, wait_timeout: Duration, interrupt_timeout: Duration, terminate_timeout: Duration, ) -> Result<ExitStatus, TerminationError>

Wait for this process to run to completion within timeout.

If the timeout is reached before the process terminated normally, external termination of the process is forced through ProcessHandle::terminate.

Note that this function may return Ok even though the timeout was reached, carrying the exit status received after sending a termination signal!

Source

pub fn into_inner(self) -> (Child, O, O)

Consumes this handle to provide the wrapped tokio::process::Child instance as well as the stdout and stderr output streams.

Trait Implementations§

Source§

impl<O: Debug + OutputStream> Debug for ProcessHandle<O>

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<O> Freeze for ProcessHandle<O>
where O: Freeze,

§

impl<O> !RefUnwindSafe for ProcessHandle<O>

§

impl<O> Send for ProcessHandle<O>
where O: Send,

§

impl<O> Sync for ProcessHandle<O>
where O: Sync,

§

impl<O> Unpin for ProcessHandle<O>
where O: Unpin,

§

impl<O> !UnwindSafe for ProcessHandle<O>

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<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, 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
Source§

impl<T> Sink for T
where T: Debug + Send + Sync + 'static,