Skip to main content

ProcessHandle

Struct ProcessHandle 

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

One process whose exit this process can wait for.

The OS tells the handle when the process exits, so nothing checks a PID on a timer, and a PID the OS later gives to another process does not change the answer:

PlatformExit event
Linux, Androida pidfd (pidfd_open, Linux 5.3 and later), readable once the process exits
macOS, FreeBSD, NetBSD, OpenBSD, DragonFlya kqueue watching EVFILT_PROC for NOTE_EXIT
Windowsa process handle, signaled once the process exits

Open it with ProcessHandle::open while the PID is known to name the process you mean, for example from the peer credentials of a connection that is still open, or with ProcessHandle::for_child for a child that has not been waited for. From then on the handle follows that process, not its PID.

Waiting reports only that the process exited. Its exit status belongs to its parent: for a child, call wait or try_wait on the child once the handle reports the exit. An error means this process could not find out, never that the watched process failed.

§Fallback without an exit event

On Linux before 5.3, where pidfd_open is missing or a seccomp policy refuses it, and on other Unix systems, the handle checks the PID instead, with a pause that grows to 50 ms between checks. That fallback has the PID’s two weaknesses: a PID reused by another process reads as still running, and, except on Linux, a child that exited but has not been waited for reads as running too. ProcessHandle::is_pid_only reports it. The crate’s waits for its own children (launch::DaemonChild, Candidate and the warmup reaper) then ask the child through try_wait instead, and do the same when the handle could not be opened at all.

Implementations§

Source§

impl ProcessHandle

Source

pub fn open(pid: ProcessId) -> Result<Self>

Watch the process that has pid now.

A process that already exited, or a PID no process has, gives a handle that reports the exit at once.

The process need not be a child. Linux takes the PID in this process’s PID namespace, and macOS lets any process be watched. FreeBSD watches only a process this user may debug and falls back to the PID for others. Windows needs the right to wait on the process, which an elevated or protected process may refuse with PermissionDenied.

A PID read from a discovery record may already name another process. Take it from the peer credentials of a live connection instead (super::peer::PeerCredentials), and open the handle while that connection is still open.

Source

pub fn for_child(child: &Child) -> Result<Self>

Watch a child of this process.

On Windows the child’s own handle keeps its PID from being reused. On Unix the PID stays the child’s until it is waited for, so open the handle before anything waits for it. A process that ignores SIGCHLD has its children reaped by the kernel as they exit, and there a child can be gone, and its PID reused, before this runs.

Source

pub fn pid(&self) -> ProcessId

The PID this handle was opened with.

Source

pub fn is_pid_only(&self) -> bool

True when this handle checks the PID because no exit event was available. See the fallback section above.

Source

pub fn has_exited(&mut self) -> Result<bool>

Whether the process has exited, without blocking.

Source

pub fn wait(&mut self) -> Result<()>

Block until the process exits.

Source

pub fn wait_until(&mut self, deadline: Instant) -> Result<bool>

Block until the process exits or deadline passes. True if it exited.

Source

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

Complete when the process exits.

On Unix this registers the descriptor with the Tokio reactor, so it needs a runtime with I/O enabled (enable_io or enable_all). On Windows a thread-pool wait wakes it. Cancelling the future stops only this wait.

Source

pub async fn exited_until(&mut self, deadline: Instant) -> Result<bool>

As Self::exited, giving up at deadline. True if it exited.

Trait Implementations§

Source§

impl Debug for ProcessHandle

Source§

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

Formats the value using the given formatter. 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<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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 = !

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

fn try_from(value: U) -> Result<T, !>

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.