Expand description
Safe Rust wrapper for Linux process file descriptors (pidfd).
This crate provides a safe, ergonomic interface to Linux’s pidfd API, which represents processes as file descriptors. Unlike traditional PIDs, pidfds cannot be reused after a process exits, making them safe from PID reuse race conditions.
The typical ways to obtain a pidfd include:
- Using
clone3withCLONE_PIDFD: On nightly Rust, usestd::process::Commandwithcreate_pidfd(true)and then callinto_pidfd()on the child process. - Clearing the
CLOEXECflag and exec’ing: Clear the close-on-exec flag usinglibc::fcntlwithlibc::F_SETFD, then exec the target process. - Passing via UNIX socket: Use
sendmsg/recvmsgon a UNIX socket to pass the file descriptor between processes. This is exposed instd::os::unix::net::UnixStream::recv_vectored_with_ancillary.
Warning: While PidFd::from_pid() exists, its use is highly discouraged. There is a race
condition where the process with the PID dies and a new process gets assigned the same recycled PID,
causing the resulting pidfd to refer to the wrong process.
§Features
- Safe process operations: Send signals, wait for exit, query process information
- PID reuse protection: Pidfds remain valid and unique even after process termination
- Modern kernel support: Uses modern kernel APIs when available, falls back to older methods
- Async support: Optional async operations via the
asyncfeature (enabled by default) - Nightly compatibility: Uses stdlib’s
PidFdon nightly, provides own implementation on stable
§Core Types
PidFd: The main type representing a process file descriptorPidFdExt: Extension trait providing additional operations (get PID, credentials, namespaces, etc.)AsyncPidFd: Async wrapper for waiting on process exit (requiresasyncfeature)PidFdCreds: Process credential information (UID, GID variants)PidFdGetNamespace: Namespace types that can be queried
§Examples
let pidfd = spawn_child();
// Query process information
let pid = pidfd.get_pid().expect("Failed to get the child PID");
let creds = pidfd.get_creds().expect("Failed to get child credentials");
println!("Process {} running as UID {}", pid, creds.euid);
// Send a signal
pidfd.send_signal(libc::SIGTERM).expect("Failed to send SIGTERM to child");
// Wait for process to exit
let status = pidfd.wait().expect("Failed to wait for child to exit");
println!("Process exited with status: {:?}", status);§Kernel Requirements
- Basic pidfd support requires Linux 5.3+
- Some operations require newer kernels (automatically detected with fallback where possible)
Structs§
- Async
PidFd - An async wrapper around
PidFdfor asynchronous process waiting. - PidFd
- A file descriptor that refers to a process.
- PidFd
Creds - Process credential information.
Enums§
- PidFd
GetNamespace - Linux namespace types that can be queried from a pidfd.