waitpidx provides Linux process waiting by PID (not limited to child processes).
It uses pidfd_open(2) + poll(2) under the hood and supports both:
- synchronous waiting
- asynchronous waiting with Tokio
- Linux only
- Kernel
>= 5.3(pidfd_open) - Rust stable (Edition 2024)
[dependencies]
waitpidx = "0.0.1"Disable default async feature when you only need sync API:
[dependencies]
waitpidx = { version = "0.0.1", default-features = false }use std::{process::Command, time::Duration};
fn main() -> std::io::Result<()> {
let mut child = Command::new("sleep").arg("0.1").spawn()?;
waitpidx::waitpid(child.id(), Some(Duration::from_secs(5)))?;
child.wait()?;
Ok(())
}use std::process::Command;
#[tokio::main(flavor = "current_thread")]
async fn main() -> std::io::Result<()> {
let mut child = Command::new("sleep").arg("0.1").spawn()?;
waitpidx::waitpid_async(child.id()).await?;
child.wait()?;
Ok(())
}waitpid(pid, timeout)- Wait for process exit with optional timeout.
- Returns
TimedOutwhen timeout expires.
waitpid_async(pid)- Async wait for process exit.
pidfd::PidFd/pidfd::AsyncPidFd- Low-level wrappers if you need reusable wait handles.
process_exists(pid)- Cheap existence check based on signal 0 semantics.
Common std::io::ErrorKind values:
InvalidInput: invalid PID (for example0), or invalid timeout conversionTimedOut: timeout reached in sync waitNotFound/PermissionDenied/ others: forwarded from OS (pidfd_open,poll, etc.)
async(default): enables Tokio-based async API
Run included examples:
cargo run --example waitpid -- <pid>
cargo run --example waitpid_async --features async -- <pid>
cargo run --example waitpid_many_async --features async -- <pid1> <pid2>Apache-2.0