diff options
| author | bors <bors@rust-lang.org> | 2022-09-02 21:08:08 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-09-02 21:08:08 +0000 |
| commit | b8169a6da07f123cda26b5903e3d6032dd00efb9 (patch) | |
| tree | 3be34c6a03cda97ef2ce1d2bef6da41f87845669 | |
| parent | bfb2016a7ea703f4ffbb9dd4ad7ad25ee4b549f5 (diff) | |
| parent | 4b3aa91b03c3dbfd05becbd890b4b06574092aab (diff) | |
| download | rust-b8169a6da07f123cda26b5903e3d6032dd00efb9.tar.gz rust-b8169a6da07f123cda26b5903e3d6032dd00efb9.zip | |
Auto merge of #97802 - Enselic:add-no_ignore_sigkill-feature, r=joshtriplett
Support `#[unix_sigpipe = "inherit|sig_dfl"]` on `fn main()` to prevent ignoring `SIGPIPE`
When enabled, programs don't have to explicitly handle `ErrorKind::BrokenPipe` any longer. Currently, the program
```rust
fn main() { loop { println!("hello world"); } }
```
will print an error if used with a short-lived pipe, e.g.
% ./main | head -n 1
hello world
thread 'main' panicked at 'failed printing to stdout: Broken pipe (os error 32)', library/std/src/io/stdio.rs:1016:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
by enabling `#[unix_sigpipe = "sig_dfl"]` like this
```rust
#![feature(unix_sigpipe)]
#[unix_sigpipe = "sig_dfl"]
fn main() { loop { println!("hello world"); } }
```
there is no error, because `SIGPIPE` will not be ignored and thus the program will be killed appropriately:
% ./main | head -n 1
hello world
The current libstd behaviour of ignoring `SIGPIPE` before `fn main()` can be explicitly requested by using `#[unix_sigpipe = "sig_ign"]`.
With `#[unix_sigpipe = "inherit"]`, no change at all is made to `SIGPIPE`, which typically means the behaviour will be the same as `#[unix_sigpipe = "sig_dfl"]`.
See https://github.com/rust-lang/rust/issues/62569 and referenced issues for discussions regarding the `SIGPIPE` problem itself
See the [this](https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Proposal.3A.20First.20step.20towards.20solving.20the.20SIGPIPE.20problem) Zulip topic for more discussions, including about this PR.
Tracking issue: https://github.com/rust-lang/rust/issues/97889
| -rw-r--r-- | src/main_shim.rs | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/src/main_shim.rs b/src/main_shim.rs index c67b6e98b32..3c024a84d90 100644 --- a/src/main_shim.rs +++ b/src/main_shim.rs @@ -1,7 +1,7 @@ use rustc_hir::LangItem; use rustc_middle::ty::subst::GenericArg; use rustc_middle::ty::AssocKind; -use rustc_session::config::EntryFnType; +use rustc_session::config::{sigpipe, EntryFnType}; use rustc_span::symbol::Ident; use crate::prelude::*; @@ -15,12 +15,12 @@ pub(crate) fn maybe_create_entry_wrapper( is_jit: bool, is_primary_cgu: bool, ) { - let (main_def_id, is_main_fn) = match tcx.entry_fn(()) { + let (main_def_id, (is_main_fn, sigpipe)) = match tcx.entry_fn(()) { Some((def_id, entry_ty)) => ( def_id, match entry_ty { - EntryFnType::Main => true, - EntryFnType::Start => false, + EntryFnType::Main { sigpipe } => (true, sigpipe), + EntryFnType::Start => (false, sigpipe::DEFAULT), }, ), None => return, @@ -35,7 +35,7 @@ pub(crate) fn maybe_create_entry_wrapper( return; } - create_entry_fn(tcx, module, unwind_context, main_def_id, is_jit, is_main_fn); + create_entry_fn(tcx, module, unwind_context, main_def_id, is_jit, is_main_fn, sigpipe); fn create_entry_fn( tcx: TyCtxt<'_>, @@ -44,6 +44,7 @@ pub(crate) fn maybe_create_entry_wrapper( rust_main_def_id: DefId, ignore_lang_start_wrapper: bool, is_main_fn: bool, + sigpipe: u8, ) { let main_ret_ty = tcx.fn_sig(rust_main_def_id).output(); // Given that `main()` has no arguments, @@ -83,6 +84,7 @@ pub(crate) fn maybe_create_entry_wrapper( bcx.switch_to_block(block); let arg_argc = bcx.append_block_param(block, m.target_config().pointer_type()); let arg_argv = bcx.append_block_param(block, m.target_config().pointer_type()); + let arg_sigpipe = bcx.ins().iconst(types::I8, sigpipe as i64); let main_func_ref = m.declare_func_in_func(main_func_id, &mut bcx.func); @@ -143,7 +145,8 @@ pub(crate) fn maybe_create_entry_wrapper( let main_val = bcx.ins().func_addr(m.target_config().pointer_type(), main_func_ref); let func_ref = m.declare_func_in_func(start_func_id, &mut bcx.func); - let call_inst = bcx.ins().call(func_ref, &[main_val, arg_argc, arg_argv]); + let call_inst = + bcx.ins().call(func_ref, &[main_val, arg_argc, arg_argv, arg_sigpipe]); bcx.inst_results(call_inst)[0] } else { // using user-defined start fn |
