Skip to content

Commit ccd2c40

Browse files
authoredApr 16, 2018
Rollup merge of rust-lang#49606 - varkor:pipe-repair, r=alexcrichton
Prevent broken pipes causing ICEs As the private `std::io::print_to` panics if there is an I/O error, which is used by `println!`, the compiler would ICE if one attempted to use a broken pipe (e.g. `rustc --help | false`). This introduces a new (private) macro `try_println!` which allows us to avoid this. As a side note, it seems this macro might be useful publicly (and actually there seems to be [a crate specifically for this purpose](https://crates.io/crates/try_print/)), though that can probably be left for a future discussion. One slight alternative approach would be to simply early exit without an error (i.e. exit code `0`), which [this comment](rust-lang#34376 (comment)) suggests is the usual approach. I've opted not to take that approach initially, because I think it's more helpful to know when there is a broken pipe. Fixes rust-lang#34376.

File tree

4 files changed

+19
-3
lines changed

4 files changed

+19
-3
lines changed
 

‎src/librustc_driver/lib.rs

+12
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,18 @@ fn run_compiler_impl<'a>(args: &[String],
547547
(result, Some(sess))
548548
}
549549

550+
#[cfg(unix)]
551+
pub fn set_sigpipe_handler() {
552+
unsafe {
553+
// Set the SIGPIPE signal handler, so that an EPIPE
554+
// will cause rustc to terminate, as expected.
555+
assert!(libc::signal(libc::SIGPIPE, libc::SIG_DFL) != libc::SIG_ERR);
556+
}
557+
}
558+
559+
#[cfg(windows)]
560+
pub fn set_sigpipe_handler() {}
561+
550562
// Extract output directory and file from matches.
551563
fn make_output(matches: &getopts::Matches) -> (Option<PathBuf>, Option<PathBuf>) {
552564
let odir = matches.opt_str("out-dir").map(|o| PathBuf::from(&o));

‎src/librustdoc/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ struct Output {
100100

101101
pub fn main() {
102102
const STACK_SIZE: usize = 32_000_000; // 32MB
103+
rustc_driver::set_sigpipe_handler();
103104
env_logger::init();
104105
let res = std::thread::Builder::new().stack_size(STACK_SIZE).spawn(move || {
105106
syntax::with_globals(move || {

‎src/libstd/sys/unix/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,11 @@ pub fn init() {
8080
reset_sigpipe();
8181
}
8282

83-
#[cfg(not(any(target_os = "emscripten", target_os="fuchsia")))]
83+
#[cfg(not(any(target_os = "emscripten", target_os = "fuchsia")))]
8484
unsafe fn reset_sigpipe() {
8585
assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != libc::SIG_ERR);
8686
}
87-
#[cfg(any(target_os = "emscripten", target_os="fuchsia"))]
87+
#[cfg(any(target_os = "emscripten", target_os = "fuchsia"))]
8888
unsafe fn reset_sigpipe() {}
8989
}
9090

‎src/rustc/rustc.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,7 @@ extern {}
2323

2424
extern crate rustc_driver;
2525

26-
fn main() { rustc_driver::main() }
26+
fn main() {
27+
rustc_driver::set_sigpipe_handler();
28+
rustc_driver::main()
29+
}

0 commit comments

Comments
 (0)
Please sign in to comment.