|
| 1 | +// Checks the signal disposition of `SIGPIPE` in child processes, and in our own |
| 2 | +// process for robustness. Without any `unix_sigpipe` attribute, `SIG_IGN` is |
| 3 | +// the default. But there is a difference in how `SIGPIPE` is treated in child |
| 4 | +// processes with and without the attribute. Search for |
| 5 | +// `unix_sigpipe_attr_specified()` in the code base to learn more. |
| 6 | +// |
| 7 | +// Note that there are many other tests for `unix_sigpipe` in |
| 8 | +// tests/ui/attributes/unix_sigpipe. |
| 9 | + |
| 10 | +#![feature(rustc_private)] |
| 11 | +#![cfg_attr(any(sig_dfl, sig_ign, inherit), feature(unix_sigpipe))] |
| 12 | + |
| 13 | +extern crate libc; |
| 14 | + |
| 15 | +#[cfg_attr(sig_dfl, unix_sigpipe = "sig_dfl")] |
| 16 | +#[cfg_attr(sig_ign, unix_sigpipe = "sig_ign")] |
| 17 | +#[cfg_attr(inherit, unix_sigpipe = "inherit")] |
| 18 | +fn main() { |
| 19 | + // By default, we get SIG_IGN but the child gets SIG_DFL. |
| 20 | + #[cfg(default)] |
| 21 | + let (we_expect, child_expects) = (libc::SIG_IGN, libc::SIG_DFL); |
| 22 | + |
| 23 | + // With #[unix_sigpipe = "sig_dfl"] we get SIG_DFL and the child does too. |
| 24 | + #[cfg(sig_dfl)] |
| 25 | + let (we_expect, child_expects) = (libc::SIG_DFL, libc::SIG_DFL); |
| 26 | + |
| 27 | + // With #[unix_sigpipe = "sig_ign"] we get SIG_IGN and the child does too. |
| 28 | + #[cfg(sig_ign)] |
| 29 | + let (we_expect, child_expects) = (libc::SIG_IGN, libc::SIG_IGN); |
| 30 | + |
| 31 | + // With #[unix_sigpipe = "inherit"] we get SIG_DFL and the child does too. |
| 32 | + #[cfg(inherit)] |
| 33 | + let (we_expect, child_expects) = (libc::SIG_DFL, libc::SIG_DFL); |
| 34 | + |
| 35 | + let actual = unsafe { |
| 36 | + let mut actual: libc::sigaction = std::mem::zeroed(); |
| 37 | + libc::sigaction(libc::SIGPIPE, std::ptr::null(), &mut actual); |
| 38 | + actual.sa_sigaction |
| 39 | + }; |
| 40 | + assert_eq!(actual, we_expect, "we did not get the SIGPIPE disposition we expect"); |
| 41 | + |
| 42 | + let child_program = std::env::args().nth(1).unwrap(); |
| 43 | + let child_expects = match child_expects { |
| 44 | + libc::SIG_DFL => "SIG_DFL", |
| 45 | + libc::SIG_IGN => "SIG_IGN", |
| 46 | + _ => unreachable!(), |
| 47 | + }; |
| 48 | + assert!( |
| 49 | + std::process::Command::new(child_program).arg(child_expects).status().unwrap().success() |
| 50 | + ); |
| 51 | +} |
0 commit comments