Skip to content
/ rust Public
forked from rust-lang/rust

Commit 527be25

Browse files
committed
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.
1 parent 21033f6 commit 527be25

File tree

3 files changed

+91
-0
lines changed

3 files changed

+91
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# ignore-cross-compile because we run the compiled code
2+
# only-unix
3+
4+
# See main.rs for a description of this test.
5+
6+
include ../tools.mk
7+
8+
all:
9+
$(RUSTC) assert-sigpipe-disposition.rs -o $(TMPDIR)/assert-sigpipe-disposition;
10+
for revision in default sig_dfl sig_ign inherit; do \
11+
echo -n "Testing revision $$revision ... "; \
12+
$(RUSTC) main.rs --cfg $$revision -o $(TMPDIR)/main.$$revision || exit 1; \
13+
$(TMPDIR)/main.$$revision $(TMPDIR)/assert-sigpipe-disposition || exit 1; \
14+
echo "ok"; \
15+
done
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#![feature(start, rustc_private)]
2+
3+
extern crate libc;
4+
5+
// Use #[start] so we don't have a runtime that messes with SIGPIPE.
6+
#[start]
7+
fn start(argc: isize, argv: *const *const u8) -> isize {
8+
assert_eq!(argc, 2, "Must pass SIG_IGN or SIG_DFL as first arg");
9+
let expected =
10+
match unsafe { std::ffi::CStr::from_ptr(*argv.offset(1) as *const i8) }.to_str().unwrap() {
11+
"SIG_IGN" => libc::SIG_IGN,
12+
"SIG_DFL" => libc::SIG_DFL,
13+
arg => panic!("Must pass SIG_IGN or SIG_DFL as first arg. Got: {}", arg),
14+
};
15+
16+
let actual = unsafe {
17+
let mut actual: libc::sigaction = std::mem::zeroed();
18+
libc::sigaction(libc::SIGPIPE, std::ptr::null(), &mut actual);
19+
actual.sa_sigaction
20+
};
21+
22+
assert_eq!(actual, expected, "actual and expected SIGPIPE disposition in child differs");
23+
24+
return 0;
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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

Comments
 (0)