|
| 1 | +//@ revisions: default sig_dfl sig_ign inherit |
| 2 | +//@ ignore-cross-compile because aux-bin does not yet support it |
| 3 | +//@ only-unix because SIGPIPE is a unix thing |
| 4 | +//@ run-pass |
| 5 | +//@ aux-bin:assert-sigpipe-disposition.rs |
| 6 | +//@ aux-crate:sigpipe_utils=sigpipe-utils.rs |
| 7 | + |
| 8 | +// Checks the signal disposition of `SIGPIPE` in child processes, and in our own |
| 9 | +// process for robustness. Without any `unix_sigpipe` attribute, `SIG_IGN` is |
| 10 | +// the default. But there is a difference in how `SIGPIPE` is treated in child |
| 11 | +// processes with and without the attribute. Search for |
| 12 | +// `unix_sigpipe_attr_specified()` in the code base to learn more. |
| 13 | + |
| 14 | +#![feature(rustc_private)] |
| 15 | +#![cfg_attr(any(sig_dfl, sig_ign, inherit), feature(unix_sigpipe))] |
| 16 | + |
| 17 | +extern crate libc; |
| 18 | +extern crate sigpipe_utils; |
| 19 | + |
| 20 | +use sigpipe_utils::*; |
| 21 | + |
| 22 | +#[cfg_attr(sig_dfl, unix_sigpipe = "sig_dfl")] |
| 23 | +#[cfg_attr(sig_ign, unix_sigpipe = "sig_ign")] |
| 24 | +#[cfg_attr(inherit, unix_sigpipe = "inherit")] |
| 25 | +fn main() { |
| 26 | + // By default we get SIG_IGN but the child gets SIG_DFL through an explicit |
| 27 | + // reset before exec: |
| 28 | + // https://github.com/rust-lang/rust/blob/bf4de3a874753bbee3323081c8b0c133444fed2d/library/std/src/sys/pal/unix/process/process_unix.rs#L363-L384 |
| 29 | + #[cfg(default)] |
| 30 | + let (we_expect, child_expects) = (SignalHandler::Ignore, "SIG_DFL"); |
| 31 | + |
| 32 | + // With #[unix_sigpipe = "sig_dfl"] we get SIG_DFL and the child does too |
| 33 | + // without any special code running before exec. |
| 34 | + #[cfg(sig_dfl)] |
| 35 | + let (we_expect, child_expects) = (SignalHandler::Default, "SIG_DFL"); |
| 36 | + |
| 37 | + // With #[unix_sigpipe = "sig_ign"] we get SIG_IGN and the child does too |
| 38 | + // without any special code running before exec. |
| 39 | + #[cfg(sig_ign)] |
| 40 | + let (we_expect, child_expects) = (SignalHandler::Ignore, "SIG_IGN"); |
| 41 | + |
| 42 | + // With #[unix_sigpipe = "inherit"] we get SIG_DFL and the child does too |
| 43 | + // without any special code running before exec. |
| 44 | + #[cfg(inherit)] |
| 45 | + let (we_expect, child_expects) = (SignalHandler::Default, "SIG_DFL"); |
| 46 | + |
| 47 | + assert_sigpipe_handler(we_expect); |
| 48 | + |
| 49 | + assert!( |
| 50 | + std::process::Command::new("./auxiliary/bin/assert-sigpipe-disposition") |
| 51 | + .arg(child_expects) |
| 52 | + .status() |
| 53 | + .unwrap() |
| 54 | + .success() |
| 55 | + ); |
| 56 | +} |
0 commit comments