summaryrefslogtreecommitdiffstats
path: root/library/std/src/sys/unix/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--library/std/src/sys/unix/mod.rs42
1 files changed, 34 insertions, 8 deletions
diff --git a/library/std/src/sys/unix/mod.rs b/library/std/src/sys/unix/mod.rs
index c84e292ea..9055a011c 100644
--- a/library/std/src/sys/unix/mod.rs
+++ b/library/std/src/sys/unix/mod.rs
@@ -163,17 +163,27 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
// See the other file for docs. NOTE: Make sure to keep them in
// sync!
mod sigpipe {
+ pub const DEFAULT: u8 = 0;
pub const INHERIT: u8 = 1;
pub const SIG_IGN: u8 = 2;
pub const SIG_DFL: u8 = 3;
}
- let handler = match sigpipe {
- sigpipe::INHERIT => None,
- sigpipe::SIG_IGN => Some(libc::SIG_IGN),
- sigpipe::SIG_DFL => Some(libc::SIG_DFL),
+ let (sigpipe_attr_specified, handler) = match sigpipe {
+ sigpipe::DEFAULT => (false, Some(libc::SIG_IGN)),
+ sigpipe::INHERIT => (true, None),
+ sigpipe::SIG_IGN => (true, Some(libc::SIG_IGN)),
+ sigpipe::SIG_DFL => (true, Some(libc::SIG_DFL)),
_ => unreachable!(),
};
+ // The bootstrap compiler doesn't know about sigpipe::DEFAULT, and always passes in
+ // SIG_IGN. This causes some tests to fail because they expect SIGPIPE to be reset to
+ // default on process spawning (which doesn't happen if #[unix_sigpipe] is specified).
+ // Since we can't differentiate between the cases here, treat SIG_IGN as DEFAULT
+ // unconditionally.
+ if sigpipe_attr_specified && !(cfg!(bootstrap) && sigpipe == sigpipe::SIG_IGN) {
+ UNIX_SIGPIPE_ATTR_SPECIFIED.store(true, crate::sync::atomic::Ordering::Relaxed);
+ }
if let Some(handler) = handler {
rtassert!(signal(libc::SIGPIPE, handler) != libc::SIG_ERR);
}
@@ -181,6 +191,26 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
}
}
+// This is set (up to once) in reset_sigpipe.
+#[cfg(not(any(
+ target_os = "espidf",
+ target_os = "emscripten",
+ target_os = "fuchsia",
+ target_os = "horizon"
+)))]
+static UNIX_SIGPIPE_ATTR_SPECIFIED: crate::sync::atomic::AtomicBool =
+ crate::sync::atomic::AtomicBool::new(false);
+
+#[cfg(not(any(
+ target_os = "espidf",
+ target_os = "emscripten",
+ target_os = "fuchsia",
+ target_os = "horizon"
+)))]
+pub(crate) fn unix_sigpipe_attr_specified() -> bool {
+ UNIX_SIGPIPE_ATTR_SPECIFIED.load(crate::sync::atomic::Ordering::Relaxed)
+}
+
// SAFETY: must be called only once during runtime cleanup.
// NOTE: this is not guaranteed to run, for example when the program aborts.
pub unsafe fn cleanup() {
@@ -352,16 +382,12 @@ cfg_if::cfg_if! {
extern "C" {}
} else if #[cfg(target_os = "macos")] {
#[link(name = "System")]
- // res_init and friends require -lresolv on macOS/iOS.
- // See #41582 and https://blog.achernya.com/2013/03/os-x-has-silly-libsystem.html
- #[link(name = "resolv")]
extern "C" {}
} else if #[cfg(any(target_os = "ios", target_os = "watchos"))] {
#[link(name = "System")]
#[link(name = "objc")]
#[link(name = "Security", kind = "framework")]
#[link(name = "Foundation", kind = "framework")]
- #[link(name = "resolv")]
extern "C" {}
} else if #[cfg(target_os = "fuchsia")] {
#[link(name = "zircon")]