summaryrefslogtreecommitdiffstats
path: root/library/std/src/rt.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/std/src/rt.rs')
-rw-r--r--library/std/src/rt.rs31
1 files changed, 28 insertions, 3 deletions
diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs
index 663537a05..98f6cc7aa 100644
--- a/library/std/src/rt.rs
+++ b/library/std/src/rt.rs
@@ -72,10 +72,29 @@ macro_rules! rtunwrap {
// Runs before `main`.
// SAFETY: must be called only once during runtime initialization.
// NOTE: this is not guaranteed to run, for example when Rust code is called externally.
+//
+// # The `sigpipe` parameter
+//
+// Since 2014, the Rust runtime on Unix has set the `SIGPIPE` handler to
+// `SIG_IGN`. Applications have good reasons to want a different behavior
+// though, so there is a `#[unix_sigpipe = "..."]` attribute on `fn main()` that
+// can be used to select how `SIGPIPE` shall be setup (if changed at all) before
+// `fn main()` is called. See <https://github.com/rust-lang/rust/issues/97889>
+// for more info.
+//
+// The `sigpipe` parameter to this function gets its value via the code that
+// rustc generates to invoke `fn lang_start()`. The reason we have `sigpipe` for
+// all platforms and not only Unix, is because std is not allowed to have `cfg`
+// directives as this high level. See the module docs in
+// `src/tools/tidy/src/pal.rs` for more info. On all other platforms, `sigpipe`
+// has a value, but its value is ignored.
+//
+// Even though it is an `u8`, it only ever has 3 values. These are documented in
+// `compiler/rustc_session/src/config/sigpipe.rs`.
#[cfg_attr(test, allow(dead_code))]
-unsafe fn init(argc: isize, argv: *const *const u8) {
+unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
unsafe {
- sys::init(argc, argv);
+ sys::init(argc, argv, sigpipe);
let main_guard = sys::thread::guard::init();
// Next, set up the current Thread with the guard information we just
@@ -107,6 +126,7 @@ fn lang_start_internal(
main: &(dyn Fn() -> i32 + Sync + crate::panic::RefUnwindSafe),
argc: isize,
argv: *const *const u8,
+ sigpipe: u8,
) -> Result<isize, !> {
use crate::{mem, panic};
let rt_abort = move |e| {
@@ -124,7 +144,7 @@ fn lang_start_internal(
// prevent libstd from accidentally introducing a panic to these functions. Another is from
// user code from `main` or, more nefariously, as described in e.g. issue #86030.
// SAFETY: Only called once during runtime initialization.
- panic::catch_unwind(move || unsafe { init(argc, argv) }).map_err(rt_abort)?;
+ panic::catch_unwind(move || unsafe { init(argc, argv, sigpipe) }).map_err(rt_abort)?;
let ret_code = panic::catch_unwind(move || panic::catch_unwind(main).unwrap_or(101) as isize)
.map_err(move |e| {
mem::forget(e);
@@ -140,11 +160,16 @@ fn lang_start<T: crate::process::Termination + 'static>(
main: fn() -> T,
argc: isize,
argv: *const *const u8,
+ #[cfg(not(bootstrap))] sigpipe: u8,
) -> isize {
let Ok(v) = lang_start_internal(
&move || crate::sys_common::backtrace::__rust_begin_short_backtrace(main).report().to_i32(),
argc,
argv,
+ #[cfg(bootstrap)]
+ 2, // Temporary inlining of sigpipe::DEFAULT until bootstrap stops being special
+ #[cfg(not(bootstrap))]
+ sigpipe,
);
v
}