forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of rust-lang#121573 - Enselic:sigpipe-child-process, r=M…
…ark-Simulacrum unix_sigpipe: Add test for SIGPIPE disposition in child processes To make it clearer what the impact would be to stop using `SIG_IGN` and instead use a noop handler, like suggested [here](rust-lang#62569 (comment)) and implemented [here](rust-lang#121578). Part of rust-lang#97889
- 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() | ||
); | ||
} |