From 05c4574f3a230cd25e2afce7a0fca21e33345dbf Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 21 Jul 2020 09:26:19 +0900 Subject: [PATCH] Declare `utmpx` on musl --- libc-test/build.rs | 9 ++- src/unix/bsd/netbsdlike/netbsd/mod.rs | 4 +- src/unix/linux_like/linux/musl/mod.rs | 97 +++++++++++++++++++++++++++ 3 files changed, 107 insertions(+), 3 deletions(-) diff --git a/libc-test/build.rs b/libc-test/build.rs index 648b0844..5cee9afb 100644 --- a/libc-test/build.rs +++ b/libc-test/build.rs @@ -2551,6 +2551,11 @@ fn test_linux(target: &str) { "statx" => true, "statx_timestamp" => true, + // On Linux, the type of `ut_exit` field of struct `utmpx` + // can be an anonymous struct, so an extra struct, + // which is absent in musl, has to be defined. + "__exit_status" if musl => true, + _ => false, } }); @@ -2672,7 +2677,9 @@ fn test_linux(target: &str) { // sigval is actually a union, but we pretend it's a struct (struct_ == "sigevent" && field == "sigev_value") || // this one is an anonymous union - (struct_ == "ff_effect" && field == "u") + (struct_ == "ff_effect" && field == "u") || + // `__exit_status` type is a patch which is absent in musl + (struct_ == "utmpx" && field == "ut_exit" && musl) }); cfg.volatile_item(|i| { diff --git a/src/unix/bsd/netbsdlike/netbsd/mod.rs b/src/unix/bsd/netbsdlike/netbsd/mod.rs index 8b3ce3e2..6ddb3257 100644 --- a/src/unix/bsd/netbsdlike/netbsd/mod.rs +++ b/src/unix/bsd/netbsdlike/netbsd/mod.rs @@ -92,7 +92,7 @@ s! { pub st_spare: [u32; 2], } - pub struct addrinfo { + pub struct addrinfo { pub ai_flags: ::c_int, pub ai_family: ::c_int, pub ai_socktype: ::c_int, @@ -286,7 +286,7 @@ s! { pub struct __exit_status { pub e_termination: u16, pub e_exit: u16, - } + } pub struct shmid_ds { pub shm_perm: ::ipc_perm, diff --git a/src/unix/linux_like/linux/musl/mod.rs b/src/unix/linux_like/linux/musl/mod.rs index f5055b25..0d427ae3 100644 --- a/src/unix/linux_like/linux/musl/mod.rs +++ b/src/unix/linux_like/linux/musl/mod.rs @@ -144,6 +144,11 @@ s! { pub imr_address: ::in_addr, pub imr_ifindex: ::c_int, } + + pub struct __exit_status { + pub e_termination: ::c_short, + pub e_exit: ::c_short, + } } s_no_extra_traits! { @@ -163,6 +168,36 @@ s_no_extra_traits! { pub mem_unit: ::c_uint, pub __reserved: [::c_char; 256], } + + // FIXME: 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 comments for now. + // ref. https://github.com/bminor/musl/commit/ + // 1e7f0fcd7ff2096904fd93a2ee6d12a2392be392 + pub struct utmpx { + pub ut_type: ::c_short, + //__ut_pad1: ::c_short, + pub ut_pid: ::pid_t, + pub ut_line: [::c_char; 32], + pub ut_id: [::c_char; 4], + pub ut_user: [::c_char; 32], + pub ut_host: [::c_char; 256], + pub ut_exit: __exit_status, + + //#[cfg(target_endian = "little")] + pub ut_session: ::c_long, + //#[cfg(target_endian = "little")] + //__ut_pad2: ::c_long, + + //#[cfg(not(target_endian = "little"))] + //__ut_pad2: ::c_int, + //#[cfg(not(target_endian = "little"))] + //pub ut_session: ::c_int, + + pub ut_tv: ::timeval, + pub ut_addr_v6: [::c_uint; 4], + __unused: [::c_char; 20], + } } cfg_if! { @@ -231,6 +266,68 @@ cfg_if! { self.__reserved.hash(state); } } + + impl PartialEq for utmpx { + fn eq(&self, other: &utmpx) -> bool { + self.ut_type == other.ut_type + //&& self.__ut_pad1 == other.__ut_pad1 + && self.ut_pid == other.ut_pid + && self.ut_line == other.ut_line + && self.ut_id == other.ut_id + && self.ut_user == other.ut_user + && self + .ut_host + .iter() + .zip(other.ut_host.iter()) + .all(|(a,b)| a == b) + && self.ut_exit == other.ut_exit + && self.ut_session == other.ut_session + //&& self.__ut_pad2 == other.__ut_pad2 + && self.ut_tv == other.ut_tv + && self.ut_addr_v6 == other.ut_addr_v6 + && self.__unused == other.__unused + } + } + + impl Eq for utmpx {} + + impl ::fmt::Debug for utmpx { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("utmpx") + .field("ut_type", &self.ut_type) + //.field("__ut_pad1", &self.__ut_pad1) + .field("ut_pid", &self.ut_pid) + .field("ut_line", &self.ut_line) + .field("ut_id", &self.ut_id) + .field("ut_user", &self.ut_user) + //FIXME: .field("ut_host", &self.ut_host) + .field("ut_exit", &self.ut_exit) + .field("ut_session", &self.ut_session) + //.field("__ut_pad2", &self.__ut_pad2) + .field("ut_tv", &self.ut_tv) + .field("ut_addr_v6", &self.ut_addr_v6) + .field("__unused", &self.__unused) + .finish() + } + } + + impl ::hash::Hash for utmpx { + fn hash(&self, state: &mut H) { + self.ut_type.hash(state); + //self.__ut_pad1.hash(state); + self.ut_pid.hash(state); + self.ut_line.hash(state); + self.ut_id.hash(state); + self.ut_user.hash(state); + self.ut_host.hash(state); + self.ut_exit.hash(state); + self.ut_session.hash(state); + //self.__ut_pad2.hash(state); + self.ut_tv.hash(state); + self.ut_addr_v6.hash(state); + self.__unused.hash(state); + } + } } }