diff --git a/build.rs b/build.rs index 845294007409d..76ca0961e4782 100644 --- a/build.rs +++ b/build.rs @@ -5,18 +5,17 @@ use std::str; fn main() { let rustc_minor_ver = rustc_minor_version().expect("Failed to get rustc version"); - let rustc_dep_of_std = - std::env::var("CARGO_FEATURE_RUSTC_DEP_OF_STD").is_ok(); - let align_cargo_feature = std::env::var("CARGO_FEATURE_ALIGN").is_ok(); + let rustc_dep_of_std = env::var("CARGO_FEATURE_RUSTC_DEP_OF_STD").is_ok(); + let align_cargo_feature = env::var("CARGO_FEATURE_ALIGN").is_ok(); - if std::env::var("CARGO_FEATURE_USE_STD").is_ok() { + if env::var("CARGO_FEATURE_USE_STD").is_ok() { println!( "cargo:warning=\"libc's use_std cargo feature is deprecated since libc 0.2.55; \ please consider using the `std` cargo feature instead\"" ); } - if std::env::var("LIBC_CI").is_ok() { + if env::var("LIBC_CI").is_ok() { if let Some(12) = which_freebsd() { println!("cargo:rustc-cfg=freebsd12"); } @@ -53,6 +52,11 @@ fn main() { if rustc_minor_ver >= 33 || rustc_dep_of_std { println!("cargo:rustc-cfg=libc_packedN"); } + + // #[thread_local] is currently unstable + if rustc_dep_of_std { + println!("cargo:rustc-cfg=libc_thread_local"); + } } fn rustc_minor_version() -> Option { diff --git a/src/lib.rs b/src/lib.rs index 2dc42702fcb7d..0f800cea0ae16 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,6 +21,7 @@ feature = "rustc-dep-of-std", feature(cfg_target_vendor, link_cfg, no_core) )] +#![cfg_attr(libc_thread_local, feature(thread_local))] // Enable extra lints: #![cfg_attr(feature = "extra_traits", deny(missing_debug_implementations))] #![deny(missing_copy_implementations, safe_packed_borrows)] diff --git a/src/unix/bsd/freebsdlike/dragonfly/errno.rs b/src/unix/bsd/freebsdlike/dragonfly/errno.rs new file mode 100644 index 0000000000000..e18036adf5c52 --- /dev/null +++ b/src/unix/bsd/freebsdlike/dragonfly/errno.rs @@ -0,0 +1,12 @@ +// DragonFlyBSD's __error function is declared with "static inline", so it must +// be implemented in the libc crate, as a pointer to a static thread_local. +f! { + pub fn __error() -> *mut ::c_int { + &mut errno + } +} + +extern { + #[thread_local] + pub static mut errno: ::c_int; +} diff --git a/src/unix/bsd/freebsdlike/dragonfly/mod.rs b/src/unix/bsd/freebsdlike/dragonfly/mod.rs index 3088b2dccd6f7..fc94fd3c7136e 100644 --- a/src/unix/bsd/freebsdlike/dragonfly/mod.rs +++ b/src/unix/bsd/freebsdlike/dragonfly/mod.rs @@ -1060,3 +1060,10 @@ extern { pub fn fstatfs(fd: ::c_int, buf: *mut statfs) -> ::c_int; pub fn uname(buf: *mut ::utsname) -> ::c_int; } + +cfg_if! { + if #[cfg(libc_thread_local)] { + mod errno; + pub use self::errno::*; + } +} diff --git a/src/unix/haiku/mod.rs b/src/unix/haiku/mod.rs index 7bb3285a2e163..c8cf8ad25d9a6 100644 --- a/src/unix/haiku/mod.rs +++ b/src/unix/haiku/mod.rs @@ -1267,6 +1267,7 @@ extern { pub fn setrlimit(resource: ::c_int, rlim: *const ::rlimit) -> ::c_int; pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + pub fn _errnop() -> *mut ::c_int; pub fn abs(i: ::c_int) -> ::c_int; pub fn atof(s: *const ::c_char) -> ::c_double; diff --git a/src/unix/redox/mod.rs b/src/unix/redox/mod.rs index 388918eb9b5dc..121bb63a6601f 100644 --- a/src/unix/redox/mod.rs +++ b/src/unix/redox/mod.rs @@ -539,6 +539,7 @@ extern { pub fn strerror_r(errnum: ::c_int, buf: *mut c_char, buflen: ::size_t) -> ::c_int; + pub fn __errno_location() -> *mut ::c_int; // malloc.h pub fn memalign(align: ::size_t, size: ::size_t) -> *mut ::c_void;