Skip to content

Commit

Permalink
Test #[unix_sigpipe = "inherit"] with both SIG_DFL and SIG_IGN
Browse files Browse the repository at this point in the history
Add a test that fails if `#[unix_sigpipe = "inherit"]` wrongly results
in `SIGPIPE` being `SIG_DFL` if the parent has `SIG_IGN`. We have no
current test for this particular case.
  • Loading branch information
Enselic committed Apr 1, 2024
1 parent defef86 commit 0e58cbd
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#![feature(unix_sigpipe, rustc_private)]

extern crate libc;

#[unix_sigpipe = "inherit"]
fn main() {
let arg1 = std::env::args()
.skip(1)
.next()
.expect("Must pass SIG_IGN or SIG_DFL as first arg");

let expected = match arg1.as_str() {
"SIG_IGN" => libc::SIG_IGN,
"SIG_DFL" => libc::SIG_DFL,
arg => panic!("Must pass SIG_IGN or SIG_DFL as first arg. Got: {}", arg),
};

let actual = unsafe {
let mut actual: libc::sigaction = std::mem::zeroed();
libc::sigaction(libc::SIGPIPE, std::ptr::null(), &mut actual);
actual.sa_sigaction
};

assert_eq!(
actual, expected,
"actual and expected SIGPIPE disposition in differs"
);
}
31 changes: 23 additions & 8 deletions tests/ui/attributes/unix_sigpipe/unix_sigpipe-inherit.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
//@ ignore-cross-compile because aux-bin does not yet support it
//@ only-unix because SIGPIPE is a unix thing
//@ aux-bin: assert-inherit-sigpipe-disposition.rs
//@ run-pass
//@ aux-build:sigpipe-utils.rs

#![feature(unix_sigpipe)]
#![feature(rustc_private, unix_sigpipe)]

#[unix_sigpipe = "inherit"]
extern crate libc;

// By default the Rust runtime resets SIGPIPE to SIG_DFL before exec:ing child
// processes so opt-out of that with `#[unix_sigpipe = "sig_dfl"]`. See
// https://github.com/rust-lang/rust/blob/bf4de3a874753bbee3323081c8b0c133444fed2d/library/std/src/sys/pal/unix/process/process_unix.rs#L359-L384
#[unix_sigpipe = "sig_dfl"]
fn main() {
extern crate sigpipe_utils;
// First expect SIG_DFL in a child process with #[unix_sigpipe = "inherit"].
assert_inherit_sigpipe_disposition("SIG_DFL");

// With SIGPIPE as SIG_IGN the same program shall get SIG_IGN instead.
unsafe {
libc::signal(libc::SIGPIPE, libc::SIG_IGN);
}
assert_inherit_sigpipe_disposition("SIG_IGN");
}

// #[unix_sigpipe = "inherit"] is active, so SIGPIPE shall NOT be ignored,
// instead the default handler shall be installed. (We assume that the
// process that runs these tests have the default handler.)
sigpipe_utils::assert_sigpipe_handler(sigpipe_utils::SignalHandler::Default);
fn assert_inherit_sigpipe_disposition(expected: &str) {
let mut cmd = std::process::Command::new("auxiliary/bin/assert-inherit-sigpipe-disposition");
cmd.arg(expected);
assert!(cmd.status().unwrap().success());
}

0 comments on commit 0e58cbd

Please sign in to comment.