pub struct TerminateOnDrop<O: OutputStream> { /* private fields */ }Expand description
A wrapper that automatically terminates a process when dropped.
§Safety Requirements
WARNING: This type requires a multithreaded tokio runtime to function correctly!
§Usage Guidelines
This type should only be used when:
- Your code is running in a multithreaded tokio runtime.
- Automatic process cleanup on drop is absolutely necessary.
§Recommended Alternatives
Instead of relying on automatic termination, prefer these safer approaches:
- Manual process termination using
ProcessHandle::terminate - Awaiting process completion using
ProcessHandle::wait_for_completion - Awaiting process completion or performing an explicit termination using
ProcessHandle::wait_for_completion_or_terminate
§Implementation Details
The drop implementation tries to terminate the process if it was neither awaited nor terminated before being dropped. If checking the current process state fails, it still attempts best-effort termination. If termination fails, a panic is raised.
Methods from Deref<Target = ProcessHandle<O>>§
Sourcepub fn id(&self) -> Option<u32>
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.
Sourcepub fn is_running(&mut self) -> RunningState
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.
Sourcepub fn stdin(&mut self) -> &mut Stdin
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();Sourcepub fn stdout(&self) -> &O
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).
Sourcepub fn stderr(&self) -> &O
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).
Sourcepub fn must_be_terminated(&mut self)
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.
Sourcepub fn must_not_be_terminated(&mut self)
pub fn must_not_be_terminated(&mut self)
Disables the kill/panic-on-drop safeguards for this handle.
Dropping the handle after calling this method will no longer signal, kill, or panic. However, this does not keep the library-owned stdio pipes alive. If the child still depends on stdin, stdout, or stderr being open, dropping the handle may still affect it.
Use plain tokio::process::Command directly when you need a child process that can
outlive the original handle without depending on captured stdio pipes.
Sourcepub fn send_interrupt_signal(&mut self) -> Result<(), Error>
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.
§Errors
Returns an error if the platform signal could not be sent.
Sourcepub fn send_terminate_signal(&mut self) -> Result<(), Error>
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.
§Errors
Returns an error if the platform signal could not be sent.
Sourcepub async fn terminate(
&mut self,
interrupt_timeout: Duration,
terminate_timeout: Duration,
) -> Result<ExitStatus, TerminationError>
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.
§Errors
Returns TerminationError if signalling or waiting for process termination fails.
Sourcepub async fn kill(&mut self) -> Result<()>
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.
§Errors
Returns an error if Tokio cannot kill the child process.
Sourcepub async fn wait_for_completion(
&mut self,
timeout: Option<Duration>,
) -> Result<ExitStatus, WaitError>
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::<BroadcastOutputStream>::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.
§Errors
Returns WaitError if waiting for the process fails or the timeout elapses.
Sourcepub async fn wait_for_completion_or_terminate(
&mut self,
wait_timeout: Duration,
interrupt_timeout: Duration,
terminate_timeout: Duration,
) -> Result<ExitStatus, TerminationError>
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!
§Errors
Returns TerminationError if termination is required and then fails.