38 lines
2.4 KiB
Markdown
38 lines
2.4 KiB
Markdown
## `sigchld` [](https://github.com/oconnor663/sigchld.rs/actions) [](https://crates.io/crates/sigchld) [](https://docs.rs/sigchld)
|
|
|
|
This crate is a low-level building block for child process management. Unix doesn't provide a
|
|
portable API for waiting for a child process to exit _with a timeout_. (Linux has `pidfd`, but
|
|
there's no equivalent on e.g. macOS.) The next best thing is waiting for the `SIGCHLD` signal,
|
|
but Unix signal handling is complicated and error-prone. This crate implements `SIGCHLD`
|
|
handling using [`signal_hook`] internally, for compatibility with other Rust signal handling
|
|
libraries. It allows any number of threads to wait for `SIGCHLD` with an optional timeout.
|
|
|
|
Note that `SIGCHLD` indicates that _any_ child process has exited, but there's no reliable way
|
|
to know _which_ child it was. You generally need to [poll your child process][try_wait] in a
|
|
loop, and wait again if it hasn't exited yet. This is still a bit error-prone, and most
|
|
applications will prefer a higher-level API that does this loop internally, like
|
|
[`shared_child`](https://docs.rs/shared_child) or [`duct`](https://docs.rs/duct).
|
|
|
|
This crate only supports Unix and doesn't build on Windows. Portable callers need to put this
|
|
crate in the `[target.'cfg(unix)'.dependencies]` section of their `Cargo.toml` and only use it
|
|
inside of `#[cfg(unix)]` blocks or similar.
|
|
|
|
## Example
|
|
|
|
```rust
|
|
let mut waiter = sigchld::Waiter::new()?;
|
|
// If SIGCHLD arrives after this point, the Waiter will buffer it.
|
|
let mut child = std::process::Command::new("sleep").arg("1").spawn()?;
|
|
// Block until *any* child exits. See also `wait_timeout` and `wait_deadline`.
|
|
waiter.wait()?;
|
|
// There's only one child process in this example, so we know that it exited. But in general
|
|
// we might not know which child woke us up, and in that case we'd need to wait and check in a
|
|
// loop. See the Waiter examples.
|
|
assert!(child.try_wait()?.is_some(), "sleep has exited");
|
|
```
|
|
|
|
[`signal_hook`]: https://docs.rs/signal-hook
|
|
[try_wait]: https://doc.rust-lang.org/std/process/struct.Child.html#method.try_wait
|
|
[`wait_timeout`]: https://docs.rs/shared_child/latest/shared_child/struct.SharedChild.html#method.wait_timeout
|
|
[`wait_deadline`]: https://docs.rs/shared_child/latest/shared_child/struct.SharedChild.html#method.wait_deadline
|