-
Notifications
You must be signed in to change notification settings - Fork 12.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
unix_sigpipe: Add test for SIGPIPE disposition in child processes
For robustness, also test the disposition in our own process even if tests in `tests/ui/attributes/unix_sigpipe` already covers it.
- Loading branch information
Showing
3 changed files
with
91 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# ignore-cross-compile because we run the compiled code | ||
# only-unix | ||
|
||
# See main.rs for a description of this test. | ||
|
||
include ../tools.mk | ||
|
||
all: | ||
$(RUSTC) assert-sigpipe-disposition.rs -o $(TMPDIR)/assert-sigpipe-disposition; | ||
for revision in default sig_dfl sig_ign inherit; do \ | ||
echo -n "Testing revision $$revision ... "; \ | ||
$(RUSTC) main.rs --cfg $$revision -o $(TMPDIR)/main.$$revision || exit 1; \ | ||
$(TMPDIR)/main.$$revision $(TMPDIR)/assert-sigpipe-disposition || exit 1; \ | ||
echo "ok"; \ | ||
done |
25 changes: 25 additions & 0 deletions
25
tests/run-make/sigpipe-in-child-processes/assert-sigpipe-disposition.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#![feature(start, rustc_private)] | ||
|
||
extern crate libc; | ||
|
||
// Use #[start] so we don't have a runtime that messes with SIGPIPE. | ||
#[start] | ||
fn start(argc: isize, argv: *const *const u8) -> isize { | ||
assert_eq!(argc, 2, "Must pass SIG_IGN or SIG_DFL as first arg"); | ||
let expected = | ||
match unsafe { std::ffi::CStr::from_ptr(*argv.offset(1) as *const i8) }.to_str().unwrap() { | ||
"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 child differs"); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Checks the signal disposition of `SIGPIPE` in child processes, and in our own | ||
// process for robustness. Without any `unix_sigpipe` attribute, `SIG_IGN` is | ||
// the default. But there is a difference in how `SIGPIPE` is treated in child | ||
// processes with and without the attribute. Search for | ||
// `unix_sigpipe_attr_specified()` in the code base to learn more. | ||
// | ||
// Note that there are many other tests for `unix_sigpipe` in | ||
// tests/ui/attributes/unix_sigpipe. | ||
|
||
#![feature(rustc_private)] | ||
#![cfg_attr(any(sig_dfl, sig_ign, inherit), feature(unix_sigpipe))] | ||
|
||
extern crate libc; | ||
|
||
#[cfg_attr(sig_dfl, unix_sigpipe = "sig_dfl")] | ||
#[cfg_attr(sig_ign, unix_sigpipe = "sig_ign")] | ||
#[cfg_attr(inherit, unix_sigpipe = "inherit")] | ||
fn main() { | ||
// By default, we get SIG_IGN but the child gets SIG_DFL. | ||
#[cfg(default)] | ||
let (we_expect, child_expects) = (libc::SIG_IGN, libc::SIG_DFL); | ||
|
||
// With #[unix_sigpipe = "sig_dfl"] we get SIG_DFL and the child does too. | ||
#[cfg(sig_dfl)] | ||
let (we_expect, child_expects) = (libc::SIG_DFL, libc::SIG_DFL); | ||
|
||
// With #[unix_sigpipe = "sig_ign"] we get SIG_IGN and the child does too. | ||
#[cfg(sig_ign)] | ||
let (we_expect, child_expects) = (libc::SIG_IGN, libc::SIG_IGN); | ||
|
||
// With #[unix_sigpipe = "inherit"] we get SIG_DFL and the child does too. | ||
#[cfg(inherit)] | ||
let (we_expect, child_expects) = (libc::SIG_DFL, libc::SIG_DFL); | ||
|
||
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, we_expect, "we did not get the SIGPIPE disposition we expect"); | ||
|
||
let child_program = std::env::args().nth(1).unwrap(); | ||
let child_expects = match child_expects { | ||
libc::SIG_DFL => "SIG_DFL", | ||
libc::SIG_IGN => "SIG_IGN", | ||
_ => unreachable!(), | ||
}; | ||
assert!( | ||
std::process::Command::new(child_program).arg(child_expects).status().unwrap().success() | ||
); | ||
} |