diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 935462b022f3b..0993a366d6014 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -195,6 +195,18 @@ jobs: env: RUST_LIBC_UNSTABLE_GNU_FILE_OFFSET_BITS: 64 artifact-tag: offset-bits64 + - target: aarch64-unknown-linux-musl + env: + RUST_LIBC_UNSTABLE_MUSL_V1_2_3: 1 + - target: arm-unknown-linux-musleabihf + env: + RUST_LIBC_UNSTABLE_MUSL_V1_2_3: 1 + - target: i686-unknown-linux-musl + env: + RUST_LIBC_UNSTABLE_MUSL_V1_2_3: 1 + - target: loongarch64-unknown-linux-musl + env: + RUST_LIBC_UNSTABLE_MUSL_V1_2_3: 1 # FIXME(ppc): SIGILL running tests, see # https://github.com/rust-lang/libc/pull/4254#issuecomment-2636288713 # - target: powerpc-unknown-linux-gnu diff --git a/build.rs b/build.rs index 5762df5419d76..27ec5f3b7aa5f 100644 --- a/build.rs +++ b/build.rs @@ -21,6 +21,7 @@ const ALLOWED_CFGS: &[&str] = &[ "libc_ctest", // Corresponds to `__USE_TIME_BITS64` in UAPI "linux_time_bits64", + "musl_v1_2_3" ]; // Extra values to allow for check-cfg. @@ -85,6 +86,13 @@ fn main() { _ => (), } + let musl_v1_2_3 = env::var("RUST_LIBC_UNSTABLE_MUSL_V1_2_3").is_ok(); + println!("cargo:rerun-if-env-changed=RUST_LIBC_UNSTABLE_MUSL_V1_2_3"); + // loongarch64 and ohos have already updated + if musl_v1_2_3 || target_os == "loongarch64" || target_env == "ohos" { + // FIXME(musl): enable time64 api as well + set_cfg("musl_v1_2_3"); + } let linux_time_bits64 = env::var("RUST_LIBC_UNSTABLE_LINUX_TIME_BITS64").is_ok(); println!("cargo:rerun-if-env-changed=RUST_LIBC_UNSTABLE_LINUX_TIME_BITS64"); if linux_time_bits64 { diff --git a/ci/install-musl.sh b/ci/install-musl.sh index 416874d916f3e..d3752a900ba6d 100755 --- a/ci/install-musl.sh +++ b/ci/install-musl.sh @@ -10,14 +10,14 @@ case ${1} in musl_version=1.2.5 ;; *) - musl_version=1.1.24 + [ -n "${RUST_LIBC_UNSTABLE_MUSL_V1_2_3:-}" ] && musl_version=1.2.3 || musl_version=1.1.24 ;; esac musl="musl-${musl_version}" # Download, configure, build, and install musl: -curl --retry 5 https://www.musl-libc.org/releases/${musl}.tar.gz | tar xzf - +curl --retry 5 "https://www.musl-libc.org/releases/${musl}.tar.gz" | tar xzf - cd "$musl" case ${1} in diff --git a/libc-test/build.rs b/libc-test/build.rs index d09044e42332e..d003f9c5640ab 100644 --- a/libc-test/build.rs +++ b/libc-test/build.rs @@ -3648,7 +3648,6 @@ fn test_linux(target: &str) { let x32 = target.contains("x32"); let x86_32 = target.contains("i686"); let x86_64 = target.contains("x86_64"); - let aarch64_musl = aarch64 && musl; let gnueabihf = target.contains("gnueabihf"); let x86_64_gnux32 = target.contains("gnux32") && x86_64; let riscv64 = target.contains("riscv64"); @@ -3656,7 +3655,13 @@ fn test_linux(target: &str) { let wasm32 = target.contains("wasm32"); let uclibc = target.contains("uclibc"); + let musl_v1_2_3 = env::var("RUST_LIBC_UNSTABLE_MUSL_V1_2_3").is_ok(); + let old_musl = musl && !musl_v1_2_3; + let mut cfg = ctest_cfg(); + if musl_v1_2_3 { + cfg.cfg("musl_v1_2_3", None); + } cfg.define("_GNU_SOURCE", None); // This macro re-defines fscanf,scanf,sscanf to link to the symbols that are // deprecated since glibc >= 2.29. This allows Rust binaries to link against @@ -4125,6 +4130,9 @@ fn test_linux(target: &str) { // FIXME(linux): Requires >= 6.4 kernel headers. "ptrace_sud_config" => true, + // Struct has changed for new musl versions + "tcp_info" if old_musl => true, + _ => false, } }); @@ -4226,9 +4234,9 @@ fn test_linux(target: &str) { if name == "PR_GET_MDWE" || name == "PR_MDWE_NO_INHERIT" || name == "PR_MDWE_REFUSE_EXEC_GAIN" || name == "PR_SET_MDWE" { return true; } - // FIXME(musl): Requires musl >= 1.2 - if name == "SO_PREFER_BUSY_POLL" - || name == "SO_BUSY_POLL_BUDGET" + // Requires musl >= 1.2 + if old_musl && (name == "SO_PREFER_BUSY_POLL" + || name == "SO_BUSY_POLL_BUDGET") { return true; } @@ -4252,6 +4260,14 @@ fn test_linux(target: &str) { { return true; } + // Values changed in newer musl versions on these arches + if old_musl && (riscv64 || x86_64) && name == "O_LARGEFILE" { + return true; + } + // Values changed in newer musl versions + if old_musl && name == "RLIM_NLIMITS" { + return true; + } } match name { // These constants are not available if gnu headers have been included @@ -4657,18 +4673,18 @@ fn test_linux(target: &str) { "getnameinfo" if uclibc => true, // FIXME(musl): This needs musl 1.2.2 or later. - "gettid" if musl => true, + "gettid" if old_musl => true, // Needs glibc 2.33 or later. "mallinfo2" => true, - "reallocarray" if musl => true, + "reallocarray" if old_musl => true, // Not defined in uclibc as of 1.0.34 "gettid" if uclibc => true, // Needs musl 1.2.3 or later. - "pthread_getname_np" if musl => true, + "pthread_getname_np" if old_musl => true, // pthread_sigqueue uses sigval, which was initially declared // as a struct but should be defined as a union. However due @@ -4762,8 +4778,8 @@ fn test_linux(target: &str) { "sched_ss_init_budget", "sched_ss_max_repl", ].contains(&field) && musl) || - // FIXME(musl): After musl 1.1.24, the type becomes `int` instead of `unsigned short`. - (struct_ == "ipc_perm" && field == "__seq" && aarch64_musl) || + // After musl 1.1.24, the type becomes `int` instead of `unsigned short`. + (struct_ == "ipc_perm" && field == "__seq" && old_musl && aarch64) || // glibc uses unnamed fields here and Rust doesn't support that yet (struct_ == "timex" && field.starts_with("__unused")) || // FIXME(linux): It now takes mode_t since glibc 2.31 on some targets. @@ -4812,8 +4828,8 @@ fn test_linux(target: &str) { (struct_ == "statvfs64" && field == "__f_spare") || // the `xsk_tx_metadata_union` field is an anonymous union (struct_ == "xsk_tx_metadata" && field == "xsk_tx_metadata_union") || - // FIXME(musl): After musl 1.2.0, the type becomes `int` instead of `long`. - (struct_ == "utmpx" && field == "ut_session") + // After musl 1.2.0, the type becomes `int` instead of `long`. + (old_musl && struct_ == "utmpx" && field == "ut_session") }); cfg.skip_roundtrip(move |s| match s { diff --git a/src/unix/linux_like/linux/arch/generic/mod.rs b/src/unix/linux_like/linux/arch/generic/mod.rs index ec3179b431f97..75cb7e19375d0 100644 --- a/src/unix/linux_like/linux/arch/generic/mod.rs +++ b/src/unix/linux_like/linux/arch/generic/mod.rs @@ -357,9 +357,6 @@ cfg_if! { pub const RLIMIT_RTPRIO: c_int = 14; pub const RLIMIT_RTTIME: c_int = 15; #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] - #[cfg(not(target_arch = "loongarch64"))] - pub const RLIM_NLIMITS: c_int = 15; - #[cfg(target_arch = "loongarch64")] pub const RLIM_NLIMITS: c_int = 16; #[allow(deprecated)] #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] diff --git a/src/unix/linux_like/linux/arch/mips/mod.rs b/src/unix/linux_like/linux/arch/mips/mod.rs index eee7cc81a47e4..1ac2340a27385 100644 --- a/src/unix/linux_like/linux/arch/mips/mod.rs +++ b/src/unix/linux_like/linux/arch/mips/mod.rs @@ -349,7 +349,7 @@ cfg_if! { pub const RLIMIT_RTPRIO: c_int = 14; pub const RLIMIT_RTTIME: c_int = 15; #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] - pub const RLIM_NLIMITS: c_int = 15; + pub const RLIM_NLIMITS: c_int = 16; #[allow(deprecated)] #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] pub const RLIMIT_NLIMITS: c_int = RLIM_NLIMITS; diff --git a/src/unix/linux_like/linux/arch/powerpc/mod.rs b/src/unix/linux_like/linux/arch/powerpc/mod.rs index 588b99a2d0f22..23fac9fba6262 100644 --- a/src/unix/linux_like/linux/arch/powerpc/mod.rs +++ b/src/unix/linux_like/linux/arch/powerpc/mod.rs @@ -330,7 +330,7 @@ cfg_if! { pub const RLIMIT_RTPRIO: c_int = 14; pub const RLIMIT_RTTIME: c_int = 15; #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] - pub const RLIM_NLIMITS: c_int = 15; + pub const RLIM_NLIMITS: c_int = 16; #[allow(deprecated)] #[deprecated(since = "0.2.64", note = "Not stable across OS versions")] pub const RLIMIT_NLIMITS: c_int = RLIM_NLIMITS; diff --git a/src/unix/linux_like/linux/musl/b32/arm/mod.rs b/src/unix/linux_like/linux/musl/b32/arm/mod.rs index 292585fc3a77a..a79b3fa3729ed 100644 --- a/src/unix/linux_like/linux/musl/b32/arm/mod.rs +++ b/src/unix/linux_like/linux/musl/b32/arm/mod.rs @@ -55,6 +55,14 @@ s! { } pub struct ipc_perm { + #[cfg(musl_v1_2_3)] + pub __key: crate::key_t, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "This field is incorrectly named and will be changed + to __key in a future release." + )] pub __ipc_perm_key: crate::key_t, pub uid: crate::uid_t, pub gid: crate::gid_t, diff --git a/src/unix/linux_like/linux/musl/b32/hexagon.rs b/src/unix/linux_like/linux/musl/b32/hexagon.rs index 4aab076e1c2d3..b687953554184 100644 --- a/src/unix/linux_like/linux/musl/b32/hexagon.rs +++ b/src/unix/linux_like/linux/musl/b32/hexagon.rs @@ -34,6 +34,14 @@ s! { } pub struct ipc_perm { + #[cfg(musl_v1_2_3)] + pub __key: crate::key_t, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "This field is incorrectly named and will be changed + to __key in a future release" + )] pub __ipc_perm_key: crate::key_t, pub uid: crate::uid_t, pub gid: crate::gid_t, diff --git a/src/unix/linux_like/linux/musl/b32/mips/mod.rs b/src/unix/linux_like/linux/musl/b32/mips/mod.rs index e0b35b6c58ea6..3f2b73decbec6 100644 --- a/src/unix/linux_like/linux/musl/b32/mips/mod.rs +++ b/src/unix/linux_like/linux/musl/b32/mips/mod.rs @@ -57,6 +57,14 @@ s! { } pub struct ipc_perm { + #[cfg(musl_v1_2_3)] + pub __key: crate::key_t, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "This field is incorrectly named and will be changed + to __key in a future release." + )] pub __ipc_perm_key: crate::key_t, pub uid: crate::uid_t, pub gid: crate::gid_t, diff --git a/src/unix/linux_like/linux/musl/b32/powerpc.rs b/src/unix/linux_like/linux/musl/b32/powerpc.rs index 0de40b15094bc..460b2d8fcf0ee 100644 --- a/src/unix/linux_like/linux/musl/b32/powerpc.rs +++ b/src/unix/linux_like/linux/musl/b32/powerpc.rs @@ -53,6 +53,14 @@ s! { } pub struct ipc_perm { + #[cfg(musl_v1_2_3)] + pub __key: crate::key_t, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "This field is incorrectly named and will be changed + to __key in a future release." + )] pub __ipc_perm_key: crate::key_t, pub uid: crate::uid_t, pub gid: crate::gid_t, diff --git a/src/unix/linux_like/linux/musl/b32/x86/mod.rs b/src/unix/linux_like/linux/musl/b32/x86/mod.rs index 22befbb0b71a5..c42bed66900e4 100644 --- a/src/unix/linux_like/linux/musl/b32/x86/mod.rs +++ b/src/unix/linux_like/linux/musl/b32/x86/mod.rs @@ -59,6 +59,14 @@ s! { } pub struct ipc_perm { + #[cfg(musl_v1_2_3)] + pub __key: crate::key_t, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "This field is incorrectly named and will be changed + to __key in a future release." + )] pub __ipc_perm_key: crate::key_t, pub uid: crate::uid_t, pub gid: crate::gid_t, diff --git a/src/unix/linux_like/linux/musl/b64/aarch64/mod.rs b/src/unix/linux_like/linux/musl/b64/aarch64/mod.rs index e84b9f563c668..243247edafc46 100644 --- a/src/unix/linux_like/linux/musl/b64/aarch64/mod.rs +++ b/src/unix/linux_like/linux/musl/b64/aarch64/mod.rs @@ -60,15 +60,32 @@ s! { } pub struct ipc_perm { + #[cfg(musl_v1_2_3)] + pub __key: crate::key_t, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "This field is incorrectly named and will be changed + to __key in a future release." + )] pub __ipc_perm_key: crate::key_t, pub uid: crate::uid_t, pub gid: crate::gid_t, pub cuid: crate::uid_t, pub cgid: crate::gid_t, pub mode: crate::mode_t, + + #[cfg(musl_v1_2_3)] + pub __seq: c_int, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "The type of this field has changed from c_ushort to c_int, + we'll follow that change in the future release." + )] pub __seq: c_ushort, - __unused1: c_ulong, - __unused2: c_ulong, + __unused1: c_long, + __unused2: c_long, } pub struct ucontext_t { diff --git a/src/unix/linux_like/linux/musl/b64/mips64.rs b/src/unix/linux_like/linux/musl/b64/mips64.rs index 33afe4e46c0d2..5cef57239fda9 100644 --- a/src/unix/linux_like/linux/musl/b64/mips64.rs +++ b/src/unix/linux_like/linux/musl/b64/mips64.rs @@ -57,6 +57,14 @@ s! { } pub struct ipc_perm { + #[cfg(musl_v1_2_3)] + pub __key: crate::key_t, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "This field is incorrectly named and will be changed + to __key in a future release." + )] pub __ipc_perm_key: crate::key_t, pub uid: crate::uid_t, pub gid: crate::gid_t, diff --git a/src/unix/linux_like/linux/musl/b64/powerpc64.rs b/src/unix/linux_like/linux/musl/b64/powerpc64.rs index fb9653bc881a0..4f3c081fb633c 100644 --- a/src/unix/linux_like/linux/musl/b64/powerpc64.rs +++ b/src/unix/linux_like/linux/musl/b64/powerpc64.rs @@ -51,6 +51,14 @@ s! { } pub struct ipc_perm { + #[cfg(musl_v1_2_3)] + pub __key: crate::key_t, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "This field is incorrectly named and will be changed + to __key in a future release." + )] pub __ipc_perm_key: crate::key_t, pub uid: crate::uid_t, pub gid: crate::gid_t, diff --git a/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs b/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs index 2b9b394d51d17..cd4ed5c66b0d9 100644 --- a/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs +++ b/src/unix/linux_like/linux/musl/b64/riscv64/mod.rs @@ -432,7 +432,7 @@ pub const SYS_landlock_restrict_self: c_long = 446; pub const O_APPEND: c_int = 1024; pub const O_DIRECT: c_int = 0x4000; pub const O_DIRECTORY: c_int = 0x10000; -pub const O_LARGEFILE: c_int = 0; +pub const O_LARGEFILE: c_int = 0o100000; pub const O_NOFOLLOW: c_int = 0x20000; pub const O_CREAT: c_int = 64; pub const O_EXCL: c_int = 128; diff --git a/src/unix/linux_like/linux/musl/b64/s390x.rs b/src/unix/linux_like/linux/musl/b64/s390x.rs index 8a274f39dfb77..fe9f798d00863 100644 --- a/src/unix/linux_like/linux/musl/b64/s390x.rs +++ b/src/unix/linux_like/linux/musl/b64/s390x.rs @@ -10,6 +10,14 @@ pub type __s64 = i64; s! { pub struct ipc_perm { + #[cfg(musl_v1_2_3)] + pub __key: crate::key_t, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "This field is incorrectly named and will be changed + to __key in a future release." + )] pub __ipc_perm_key: crate::key_t, pub uid: crate::uid_t, pub gid: crate::gid_t, diff --git a/src/unix/linux_like/linux/musl/b64/wasm32/mod.rs b/src/unix/linux_like/linux/musl/b64/wasm32/mod.rs index 3ac15b8a9349d..3f7a6098297f5 100644 --- a/src/unix/linux_like/linux/musl/b64/wasm32/mod.rs +++ b/src/unix/linux_like/linux/musl/b64/wasm32/mod.rs @@ -53,6 +53,14 @@ s! { } pub struct ipc_perm { + #[cfg(musl_v1_2_3)] + pub __key: crate::key_t, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "This field is incorrectly named and will be changed + to __key in a future release." + )] pub __ipc_perm_key: crate::key_t, pub uid: crate::uid_t, pub gid: crate::gid_t, diff --git a/src/unix/linux_like/linux/musl/b64/x86_64/mod.rs b/src/unix/linux_like/linux/musl/b64/x86_64/mod.rs index b44b54de65953..c02744c5183dd 100644 --- a/src/unix/linux_like/linux/musl/b64/x86_64/mod.rs +++ b/src/unix/linux_like/linux/musl/b64/x86_64/mod.rs @@ -112,6 +112,14 @@ s! { } pub struct ipc_perm { + #[cfg(musl_v1_2_3)] + pub __key: crate::key_t, + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "This field is incorrectly named and will be changed + to __key in a future release." + )] pub __ipc_perm_key: crate::key_t, pub uid: crate::uid_t, pub gid: crate::gid_t, @@ -701,7 +709,7 @@ pub const MAP_32BIT: c_int = 0x0040; pub const O_APPEND: c_int = 1024; pub const O_DIRECT: c_int = 0x4000; pub const O_DIRECTORY: c_int = 0x10000; -pub const O_LARGEFILE: c_int = 0; +pub const O_LARGEFILE: c_int = 0o0100000; pub const O_NOFOLLOW: c_int = 0x20000; pub const O_CREAT: c_int = 64; pub const O_EXCL: c_int = 128; diff --git a/src/unix/linux_like/linux/musl/mod.rs b/src/unix/linux_like/linux/musl/mod.rs index d3fc09201c730..56bb64cf7675e 100644 --- a/src/unix/linux_like/linux/musl/mod.rs +++ b/src/unix/linux_like/linux/musl/mod.rs @@ -303,16 +303,11 @@ s! { pub tcpi_probes: u8, pub tcpi_backoff: u8, pub tcpi_options: u8, - /* - * FIXME(musl): enable on all targets once musl headers are more up to date - */ /// This contains the bitfields `tcpi_snd_wscale` and `tcpi_rcv_wscale`. /// Each is 4 bits. - #[cfg(target_arch = "loongarch64")] pub tcpi_snd_rcv_wscale: u8, /// This contains the bitfields `tcpi_delivery_rate_app_limited` (1 bit) and /// `tcpi_fastopen_client_fail` (2 bits). - #[cfg(target_arch = "loongarch64")] pub tcpi_delivery_fastopen_bitfields: u8, pub tcpi_rto: u32, pub tcpi_ato: u32, @@ -358,10 +353,7 @@ s! { pub tcpi_bytes_retrans: u64, pub tcpi_dsack_dups: u32, pub tcpi_reord_seen: u32, - // FIXME(musl): enable on all targets once CI musl is updated - #[cfg(target_arch = "loongarch64")] pub tcpi_rcv_ooopack: u32, - #[cfg(target_arch = "loongarch64")] pub tcpi_snd_wnd: u32, } @@ -440,13 +432,6 @@ s_no_extra_traits! { pub __reserved: [c_char; 256], } - // FIXME(musl): musl added paddings and adjusted - // layout in 1.2.0 but our CI is still 1.1.24. - // So, I'm leaving some fields as cfg for now. - // ref. https://github.com/bminor/musl/commit/ - // 1e7f0fcd7ff2096904fd93a2ee6d12a2392be392 - // - // OpenHarmony uses the musl 1.2 layout. pub struct utmpx { pub ut_type: c_short, __ut_pad1: c_short, @@ -457,31 +442,24 @@ s_no_extra_traits! { pub ut_host: [c_char; 256], pub ut_exit: __exit_status, - #[cfg(target_env = "musl")] - #[cfg(not(target_arch = "loongarch64"))] + #[cfg(not(musl_v1_2_3))] + #[deprecated( + since = "0.2.173", + note = "The ABI of this field has changed from c_long to c_int with padding, \ + we'll follow that change in the future release. See #4443 for more info." + )] pub ut_session: c_long, - #[cfg(target_env = "musl")] - #[cfg(target_arch = "loongarch64")] - pub ut_session: c_int, - - #[cfg(target_env = "musl")] - #[cfg(target_arch = "loongarch64")] + #[cfg(musl_v1_2_3)] + #[cfg(not(target_endian = "little"))] __ut_pad2: c_int, - #[cfg(target_env = "ohos")] - #[cfg(target_endian = "little")] + #[cfg(musl_v1_2_3)] pub ut_session: c_int, - #[cfg(target_env = "ohos")] - #[cfg(target_endian = "little")] - __ut_pad2: c_int, - #[cfg(target_env = "ohos")] - #[cfg(not(target_endian = "little"))] + #[cfg(musl_v1_2_3)] + #[cfg(target_endian = "little")] __ut_pad2: c_int, - #[cfg(target_env = "ohos")] - #[cfg(not(target_endian = "little"))] - pub ut_session: c_int, pub ut_tv: crate::timeval, pub ut_addr_v6: [c_uint; 4], @@ -557,6 +535,7 @@ cfg_if! { } impl PartialEq for utmpx { + #[allow(deprecated)] fn eq(&self, other: &utmpx) -> bool { self.ut_type == other.ut_type //&& self.__ut_pad1 == other.__ut_pad1 @@ -581,6 +560,7 @@ cfg_if! { impl Eq for utmpx {} impl fmt::Debug for utmpx { + #[allow(deprecated)] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { f.debug_struct("utmpx") .field("ut_type", &self.ut_type) @@ -601,6 +581,7 @@ cfg_if! { } impl hash::Hash for utmpx { + #[allow(deprecated)] fn hash(&self, state: &mut H) { self.ut_type.hash(state); //self.__ut_pad1.hash(state);