diff --git a/Cargo.toml b/Cargo.toml index 120fbe19c662de2248790f546c36bec3ba61bdcd..cf54d45a6e5a0b3bb870994d6ce453e17456a201 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,8 +26,9 @@ rustc-std-workspace-core = { version = "1.0.0", optional = true } default = ["std"] std = [] align = [] -rustc-dep-of-std = ['align', 'rustc-std-workspace-core'] +rustc-dep-of-std = ['align', 'rustc-std-workspace-core', 'unstable'] extra_traits = [] +unstable = [] # use_std is deprecated, use `std` instead use_std = [ 'std' ] diff --git a/README.md b/README.md index dc5ff04fccff7f987d0adb19ab19d1ce17c98a92..1af0b1c2070ad3c9e48eb574902a7680c6a42349 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,9 @@ libc = "0.2" * `extra_traits`: all `struct`s implemented in `libc` are `Copy` and `Clone`. This feature derives `Debug`, `Eq`, `Hash`, and `PartialEq`. +* `unstable`: enable currently unstable bindings. Right now, this just allows + bindings to `#[thread_local]` statics on certain platforms. Requires nightly. + * **deprecated**: `use_std` is deprecated, and is equivalent to `std`. ## Rust version support diff --git a/build.rs b/build.rs index 845294007409dc180c4f3bcc713cea31c7534fc5..c997e6acfd3e7180d75b68f68dc485199bf5b04e 100644 --- a/build.rs +++ b/build.rs @@ -5,18 +5,18 @@ 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(); + let unstable_cargo_feature = env::var("CARGO_FEATURE_UNSTABLE").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 +53,11 @@ fn main() { if rustc_minor_ver >= 33 || rustc_dep_of_std { println!("cargo:rustc-cfg=libc_packedN"); } + + // #[thread_local] is currently unstable + if unstable_cargo_feature || rustc_dep_of_std { + println!("cargo:rustc-cfg=libc_thread_local"); + } } fn rustc_minor_version() -> Option<u32> { diff --git a/src/lib.rs b/src/lib.rs index 2dc42702fcb7d181a9b023a0918cc654c0d4194b..0f800cea0ae16e192dc4ef44a31a894721d6c42a 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 0000000000000000000000000000000000000000..e18036adf5c52e0155a5dc5f7fffc39920307a26 --- /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 d1e0a473ab6702bc28568b5b4b2bec569a6b9e62..fc94fd3c7136e5c65be917d411993c0c095490ba 100644 --- a/src/unix/bsd/freebsdlike/dragonfly/mod.rs +++ b/src/unix/bsd/freebsdlike/dragonfly/mod.rs @@ -1036,18 +1036,9 @@ f! { (_CMSG_ALIGN(::mem::size_of::<::cmsghdr>()) + _CMSG_ALIGN(length as usize)) as ::c_uint } - - #[cfg(libc_thread_local)] - pub fn __error() -> *mut ::c_int { - &mut errno - } } extern { - #[cfg(libc_thread_local)] - #[thread_local] - static mut errno: ::c_int; - pub fn setgrent(); pub fn mprotect(addr: *mut ::c_void, len: ::size_t, prot: ::c_int) -> ::c_int; @@ -1069,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::*; + } +}