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
This commit is contained in:
commit
8c6ce6b91b
46 changed files with 482 additions and 43 deletions
|
@ -389,15 +389,14 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||
|
||||
let main_llfn = cx.get_fn_addr(instance);
|
||||
|
||||
let use_start_lang_item = EntryFnType::Start != entry_type;
|
||||
let entry_fn = create_entry_fn::<Bx>(cx, main_llfn, main_def_id, use_start_lang_item);
|
||||
let entry_fn = create_entry_fn::<Bx>(cx, main_llfn, main_def_id, entry_type);
|
||||
return Some(entry_fn);
|
||||
|
||||
fn create_entry_fn<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
||||
cx: &'a Bx::CodegenCx,
|
||||
rust_main: Bx::Value,
|
||||
rust_main_def_id: DefId,
|
||||
use_start_lang_item: bool,
|
||||
entry_type: EntryFnType,
|
||||
) -> Bx::Function {
|
||||
// The entry function is either `int main(void)` or `int main(int argc, char **argv)`,
|
||||
// depending on whether the target needs `argc` and `argv` to be passed in.
|
||||
|
@ -442,7 +441,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||
let i8pp_ty = cx.type_ptr_to(cx.type_i8p());
|
||||
let (arg_argc, arg_argv) = get_argc_argv(cx, &mut bx);
|
||||
|
||||
let (start_fn, start_ty, args) = if use_start_lang_item {
|
||||
let (start_fn, start_ty, args) = if let EntryFnType::Main { sigpipe } = entry_type {
|
||||
let start_def_id = cx.tcx().require_lang_item(LangItem::Start, None);
|
||||
let start_fn = cx.get_fn_addr(
|
||||
ty::Instance::resolve(
|
||||
|
@ -454,8 +453,13 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
|
|||
.unwrap()
|
||||
.unwrap(),
|
||||
);
|
||||
let start_ty = cx.type_func(&[cx.val_ty(rust_main), isize_ty, i8pp_ty], isize_ty);
|
||||
(start_fn, start_ty, vec![rust_main, arg_argc, arg_argv])
|
||||
|
||||
let i8_ty = cx.type_i8();
|
||||
let arg_sigpipe = bx.const_u8(sigpipe);
|
||||
|
||||
let start_ty =
|
||||
cx.type_func(&[cx.val_ty(rust_main), isize_ty, i8pp_ty, i8_ty], isize_ty);
|
||||
(start_fn, start_ty, vec![rust_main, arg_argc, arg_argv, arg_sigpipe])
|
||||
} else {
|
||||
debug!("using user-defined start fn");
|
||||
let start_ty = cx.type_func(&[isize_ty, i8pp_ty], isize_ty);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue