diff --git a/build.rs b/build.rs index 0e40178638342..2ca7c97e18353 100644 --- a/build.rs +++ b/build.rs @@ -72,6 +72,11 @@ fn main() { println!("cargo:rustc-cfg=libc_cfg_target_vendor"); } + // Rust >= 1.40 supports #[non_exhaustive]. + if rustc_minor_ver >= 40 || rustc_dep_of_std { + println!("cargo:rustc-cfg=libc_non_exhaustive"); + } + if rustc_minor_ver >= 51 || rustc_dep_of_std { println!("cargo:rustc-cfg=libc_ptr_addr_of"); } diff --git a/libc-test/build.rs b/libc-test/build.rs index c24986ff8d0d8..6c603b98485b6 100644 --- a/libc-test/build.rs +++ b/libc-test/build.rs @@ -2653,6 +2653,8 @@ fn test_linux(target: &str) { "linux/netfilter_ipv6.h", "linux/netfilter_ipv6/ip6_tables.h", "linux/netlink.h", + // FIXME: requires more recent kernel headers: + // "linux/openat2.h", "linux/quota.h", "linux/random.h", "linux/reboot.h", @@ -2794,6 +2796,9 @@ fn test_linux(target: &str) { // Requires glibc 2.33 or newer. "mallinfo2" => true, + // Might differ between kernel versions + "open_how" => true, + _ => false, } }); @@ -2932,6 +2937,14 @@ fn test_linux(target: &str) { | "CLOSE_RANGE_UNSHARE" | "CLOSE_RANGE_CLOEXEC" => true, + // FIXME: requires more recent kernel headers: + | "RESOLVE_BENEATH" + | "RESOLVE_CACHED" + | "RESOLVE_IN_ROOT" + | "RESOLVE_NO_MAGICLINKS" + | "RESOLVE_NO_SYMLINKS" + | "RESOLVE_NO_XDEV" => true, + // FIXME: Not currently available in headers on ARM, MIPS and musl. "NETLINK_GET_STRICT_CHK" if arm || mips || musl => true, diff --git a/libc-test/semver/linux.txt b/libc-test/semver/linux.txt index beb9d0765698d..7ac6fcd83466e 100644 --- a/libc-test/semver/linux.txt +++ b/libc-test/semver/linux.txt @@ -1752,6 +1752,12 @@ RENAME_NOREPLACE RENAME_WHITEOUT REP_CNT REP_MAX +RESOLVE_BENEATH +RESOLVE_CACHED +RESOLVE_IN_ROOT +RESOLVE_NO_MAGICLINKS +RESOLVE_NO_SYMLINKS +RESOLVE_NO_XDEV RLIMIT_AS RLIMIT_CORE RLIMIT_CPU @@ -2849,6 +2855,7 @@ nlmsgerr nlmsghdr off64_t open64 +open_how open_memstream openat openat64 diff --git a/src/unix/linux_like/linux/mod.rs b/src/unix/linux_like/linux/mod.rs index 6353ecf8b693e..141dbef22b6ff 100644 --- a/src/unix/linux_like/linux/mod.rs +++ b/src/unix/linux_like/linux/mod.rs @@ -1824,6 +1824,14 @@ pub const MFD_HUGETLB: ::c_uint = 0x0004; pub const CLOSE_RANGE_UNSHARE: ::c_uint = 1 << 1; pub const CLOSE_RANGE_CLOEXEC: ::c_uint = 1 << 2; +// linux/openat2.h +pub const RESOLVE_NO_XDEV: ::__u64 = 0x01; +pub const RESOLVE_NO_MAGICLINKS: ::__u64 = 0x02; +pub const RESOLVE_NO_SYMLINKS: ::__u64 = 0x04; +pub const RESOLVE_BENEATH: ::__u64 = 0x08; +pub const RESOLVE_IN_ROOT: ::__u64 = 0x10; +pub const RESOLVE_CACHED: ::__u64 = 0x20; + // these are used in the p_type field of Elf32_Phdr and Elf64_Phdr, which has // the type Elf32Word and Elf64Word respectively. Luckily, both of those are u32 // so we can use that type here to avoid having to cast. @@ -3942,3 +3950,10 @@ cfg_if! { } } expand_align!(); + +cfg_if! { + if #[cfg(libc_non_exhaustive)] { + mod non_exhaustive; + pub use self::non_exhaustive::*; + } +} diff --git a/src/unix/linux_like/linux/non_exhaustive.rs b/src/unix/linux_like/linux/non_exhaustive.rs new file mode 100644 index 0000000000000..e2e2cb847ac65 --- /dev/null +++ b/src/unix/linux_like/linux/non_exhaustive.rs @@ -0,0 +1,9 @@ +s! { + // linux/openat2.h + #[non_exhaustive] + pub struct open_how { + pub flags: ::__u64, + pub mode: ::__u64, + pub resolve: ::__u64, + } +}