From 177a0a538b65cc95b94a8ac28cd8d646e434d8c6 Mon Sep 17 00:00:00 2001 From: Bryant Mairs Date: Fri, 18 Jan 2019 18:36:28 -0800 Subject: [PATCH] Implement PartialEq,Eq for all types --- Cargo.toml | 1 + README.md | 9 + src/macros.rs | 15 +- src/unix/notbsd/linux/mod.rs | 271 +++++++++++++--------- src/unix/notbsd/linux/other/b64/x86_64.rs | 81 +++++-- src/unix/notbsd/linux/other/mod.rs | 93 +++++--- src/unix/notbsd/mod.rs | 82 +++++-- 7 files changed, 359 insertions(+), 193 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 1d61dad1db472..6746ee9c3c96e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ default = ["use_std"] use_std = [] align = [] rustc-dep-of-std = ['align', 'rustc-std-workspace-core'] +extra_traits = [] [workspace] members = ["libc-test"] diff --git a/README.md b/README.md index 636f10e4ec2d6..776b2bc570bc7 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,15 @@ activate the *align* feature. This requires Rust 1.25 or newer: libc = { version = "0.2", features = ["align"] } ``` +All structs implemented by the libc crate have the `Copy` and `Clone` traits +implemented for them. The additional traits of `PartialEq` and `Eq` can be +enabled with the *extra_traits* feature: + +```toml +[dependencies] +libc = { version = "0.2", features = ["extra_traits"] } +``` + ## What is libc? The primary purpose of this crate is to provide all of the definitions necessary diff --git a/src/macros.rs b/src/macros.rs index 77205788c8a6d..f95399a6610fb 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -39,11 +39,20 @@ macro_rules! s { __item! { #[repr(C)] $(#[$attr])* + #[derive(Clone, Copy)] + #[cfg_attr(feature = "extra_traits", derive(Eq, PartialEq))] pub $t $i { $($field)* } } - impl ::dox::Copy for $i {} - impl ::dox::Clone for $i { - fn clone(&self) -> $i { *self } + )*) +} + +macro_rules! s_no_extra_traits { + ($($(#[$attr:meta])* pub $t:ident $i:ident { $($field:tt)* })*) => ($( + __item! { + #[repr(C)] + $(#[$attr])* + #[derive(Clone, Copy)] + pub $t $i { $($field)* } } )*) } diff --git a/src/unix/notbsd/linux/mod.rs b/src/unix/notbsd/linux/mod.rs index 8669a06ca5954..435d9b81c1119 100644 --- a/src/unix/notbsd/linux/mod.rs +++ b/src/unix/notbsd/linux/mod.rs @@ -41,22 +41,6 @@ pub type Elf64_Section = u16; pub enum fpos64_t {} // TODO: fill this out with a struct s! { - pub struct dirent { - pub d_ino: ::ino_t, - pub d_off: ::off_t, - pub d_reclen: ::c_ushort, - pub d_type: ::c_uchar, - pub d_name: [::c_char; 256], - } - - pub struct dirent64 { - pub d_ino: ::ino64_t, - pub d_off: ::off64_t, - pub d_reclen: ::c_ushort, - pub d_type: ::c_uchar, - pub d_name: [::c_char; 256], - } - pub struct rlimit64 { pub rlim_cur: rlim64_t, pub rlim_max: rlim64_t, @@ -75,74 +59,6 @@ s! { __unused5: *mut ::c_void, } - #[cfg_attr(all(feature = "align", - target_pointer_width = "32", - any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc", - target_arch = "x86_64", - target_arch = "x86")), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - any(target_pointer_width = "64", - not(any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc", - target_arch = "x86_64", - target_arch = "x86")))), - repr(align(8)))] - pub struct pthread_mutex_t { - #[cfg(all(not(feature = "align"), - any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc", - all(target_arch = "x86_64", - target_pointer_width = "32"))))] - __align: [::c_long; 0], - #[cfg(not(any(feature = "align", - target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc", - all(target_arch = "x86_64", - target_pointer_width = "32"))))] - __align: [::c_longlong; 0], - size: [u8; __SIZEOF_PTHREAD_MUTEX_T], - } - - #[cfg_attr(all(feature = "align", - target_pointer_width = "32", - any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc", - target_arch = "x86_64", - target_arch = "x86")), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - any(target_pointer_width = "64", - not(any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc", - target_arch = "x86_64", - target_arch = "x86")))), - repr(align(8)))] - pub struct pthread_rwlock_t { - #[cfg(all(not(feature = "align"), - any(target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc", - all(target_arch = "x86_64", - target_pointer_width = "32"))))] - __align: [::c_long; 0], - #[cfg(not(any(feature = "align", - target_arch = "mips", - target_arch = "arm", - target_arch = "powerpc", - all(target_arch = "x86_64", - target_pointer_width = "32"))))] - __align: [::c_longlong; 0], - size: [u8; __SIZEOF_PTHREAD_RWLOCK_T], - } - #[cfg_attr(all(feature = "align", any(target_pointer_width = "32", target_arch = "x86_64", target_arch = "powerpc64", @@ -188,30 +104,6 @@ s! { size: [u8; __SIZEOF_PTHREAD_RWLOCKATTR_T], } - #[cfg_attr(all(feature = "align", - target_env = "musl", - target_pointer_width = "32"), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - target_env = "musl", - target_pointer_width = "64"), - repr(align(8)))] - #[cfg_attr(all(feature = "align", - not(target_env = "musl"), - target_arch = "x86"), - repr(align(4)))] - #[cfg_attr(all(feature = "align", - not(target_env = "musl"), - not(target_arch = "x86")), - repr(align(8)))] - pub struct pthread_cond_t { - #[cfg(all(not(feature = "align"), target_env = "musl"))] - __align: [*const ::c_void; 0], - #[cfg(not(any(feature = "align", target_env = "musl")))] - __align: [::c_longlong; 0], - size: [u8; __SIZEOF_PTHREAD_COND_T], - } - #[cfg_attr(feature = "align", repr(align(4)))] pub struct pthread_condattr_t { #[cfg(not(feature = "align"))] @@ -657,6 +549,169 @@ s! { } } +s_no_extra_traits!{ + pub struct dirent { + pub d_ino: ::ino_t, + pub d_off: ::off_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + pub struct dirent64 { + pub d_ino: ::ino64_t, + pub d_off: ::off64_t, + pub d_reclen: ::c_ushort, + pub d_type: ::c_uchar, + pub d_name: [::c_char; 256], + } + + #[cfg_attr(all(feature = "align", + target_env = "musl", + target_pointer_width = "32"), + repr(align(4)))] + #[cfg_attr(all(feature = "align", + target_env = "musl", + target_pointer_width = "64"), + repr(align(8)))] + #[cfg_attr(all(feature = "align", + not(target_env = "musl"), + target_arch = "x86"), + repr(align(4)))] + #[cfg_attr(all(feature = "align", + not(target_env = "musl"), + not(target_arch = "x86")), + repr(align(8)))] + pub struct pthread_cond_t { + #[cfg(all(not(feature = "align"), target_env = "musl"))] + __align: [*const ::c_void; 0], + #[cfg(not(any(feature = "align", target_env = "musl")))] + __align: [::c_longlong; 0], + size: [u8; __SIZEOF_PTHREAD_COND_T], + } + + #[cfg_attr(all(feature = "align", + target_pointer_width = "32", + any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc", + target_arch = "x86_64", + target_arch = "x86")), + repr(align(4)))] + #[cfg_attr(all(feature = "align", + any(target_pointer_width = "64", + not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc", + target_arch = "x86_64", + target_arch = "x86")))), + repr(align(8)))] + pub struct pthread_mutex_t { + #[cfg(all(not(feature = "align"), + any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc", + all(target_arch = "x86_64", + target_pointer_width = "32"))))] + __align: [::c_long; 0], + #[cfg(not(any(feature = "align", + target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc", + all(target_arch = "x86_64", + target_pointer_width = "32"))))] + __align: [::c_longlong; 0], + size: [u8; __SIZEOF_PTHREAD_MUTEX_T], + } + + #[cfg_attr(all(feature = "align", + target_pointer_width = "32", + any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc", + target_arch = "x86_64", + target_arch = "x86")), + repr(align(4)))] + #[cfg_attr(all(feature = "align", + any(target_pointer_width = "64", + not(any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc", + target_arch = "x86_64", + target_arch = "x86")))), + repr(align(8)))] + pub struct pthread_rwlock_t { + #[cfg(all(not(feature = "align"), + any(target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc", + all(target_arch = "x86_64", + target_pointer_width = "32"))))] + __align: [::c_long; 0], + #[cfg(not(any(feature = "align", + target_arch = "mips", + target_arch = "arm", + target_arch = "powerpc", + all(target_arch = "x86_64", + target_pointer_width = "32"))))] + __align: [::c_longlong; 0], + size: [u8; __SIZEOF_PTHREAD_RWLOCK_T], + } +} + +#[cfg(feature = "extra_traits")] +impl PartialEq for dirent { + fn eq(&self, other: &dirent) -> bool { + self.d_ino == other.d_ino && + self.d_off == other.d_off && + self.d_reclen == other.d_reclen && + self.d_type == other.d_type && + self.d_name.iter().zip(other.d_name.iter()).all(|(a,b)| a == b) + } +} +#[cfg(feature = "extra_traits")] +impl Eq for dirent {} + +#[cfg(feature = "extra_traits")] +impl PartialEq for dirent64 { + fn eq(&self, other: &dirent64) -> bool { + self.d_ino == other.d_ino && + self.d_off == other.d_off && + self.d_reclen == other.d_reclen && + self.d_type == other.d_type && + self.d_name.iter().zip(other.d_name.iter()).all(|(a,b)| a == b) + } +} +#[cfg(feature = "extra_traits")] +impl Eq for dirent64 {} + +#[cfg(feature = "extra_traits")] +impl PartialEq for pthread_cond_t { + fn eq(&self, other: &pthread_cond_t) -> bool { + self.size.iter().zip(other.size.iter()).all(|(a,b)| a == b) + } +} +#[cfg(feature = "extra_traits")] +impl Eq for pthread_cond_t {} + +#[cfg(feature = "extra_traits")] +impl PartialEq for pthread_mutex_t { + fn eq(&self, other: &pthread_mutex_t) -> bool { + self.size.iter().zip(other.size.iter()).all(|(a,b)| a == b) + } +} +#[cfg(feature = "extra_traits")] +impl Eq for pthread_mutex_t {} + +#[cfg(feature = "extra_traits")] +impl PartialEq for pthread_rwlock_t { + fn eq(&self, other: &pthread_rwlock_t) -> bool { + self.size.iter().zip(other.size.iter()).all(|(a,b)| a == b) + } +} +#[cfg(feature = "extra_traits")] +impl Eq for pthread_rwlock_t {} + pub const ABDAY_1: ::nl_item = 0x20000; pub const ABDAY_2: ::nl_item = 0x20001; pub const ABDAY_3: ::nl_item = 0x20002; diff --git a/src/unix/notbsd/linux/other/b64/x86_64.rs b/src/unix/notbsd/linux/other/b64/x86_64.rs index 0d7137e75c036..915c46ca0e235 100644 --- a/src/unix/notbsd/linux/other/b64/x86_64.rs +++ b/src/unix/notbsd/linux/other/b64/x86_64.rs @@ -112,20 +112,6 @@ s! { __private: [u64; 12], } - pub struct user_fpregs_struct { - pub cwd: ::c_ushort, - pub swd: ::c_ushort, - pub ftw: ::c_ushort, - pub fop: ::c_ushort, - pub rip: ::c_ulonglong, - pub rdp: ::c_ulonglong, - pub mxcsr: ::c_uint, - pub mxcr_mask: ::c_uint, - pub st_space: [::c_uint; 32], - pub xmm_space: [::c_uint; 64], - padding: [::c_uint; 24], - } - pub struct user_regs_struct { pub r15: ::c_ulonglong, pub r14: ::c_ulonglong, @@ -184,15 +170,6 @@ s! { __private: [u64; 8], } - pub struct ucontext_t { - pub uc_flags: ::c_ulong, - pub uc_link: *mut ucontext_t, - pub uc_stack: ::stack_t, - pub uc_mcontext: mcontext_t, - pub uc_sigmask: ::sigset_t, - __private: [u8; 512], - } - pub struct ipc_perm { pub __key: ::key_t, pub uid: ::uid_t, @@ -232,6 +209,64 @@ s! { } } +s_no_extra_traits! { + pub struct user_fpregs_struct { + pub cwd: ::c_ushort, + pub swd: ::c_ushort, + pub ftw: ::c_ushort, + pub fop: ::c_ushort, + pub rip: ::c_ulonglong, + pub rdp: ::c_ulonglong, + pub mxcsr: ::c_uint, + pub mxcr_mask: ::c_uint, + pub st_space: [::c_uint; 32], + pub xmm_space: [::c_uint; 64], + padding: [::c_uint; 24], + } + + pub struct ucontext_t { + pub uc_flags: ::c_ulong, + pub uc_link: *mut ucontext_t, + pub uc_stack: ::stack_t, + pub uc_mcontext: mcontext_t, + pub uc_sigmask: ::sigset_t, + __private: [u8; 512], + } +} + +#[cfg(feature = "extra_traits")] +impl PartialEq for user_fpregs_struct { + fn eq(&self, other: &user_fpregs_struct) -> bool { + self.cwd == other.cwd && + self.swd == other.swd && + self.ftw == other.ftw && + self.fop == other.fop && + self.rip == other.rip && + self.rdp == other.rdp && + self.mxcsr == other.mxcsr && + self.mxcr_mask == other.mxcr_mask && + self.st_space == other.st_space && + self.xmm_space.iter().zip(other.xmm_space.iter()).all(|(a,b)| a == b) + // Ignore padding field + } +} +#[cfg(feature = "extra_traits")] +impl Eq for user_fpregs_struct {} + +#[cfg(feature = "extra_traits")] +impl PartialEq for ucontext_t { + fn eq(&self, other: &ucontext_t) -> bool { + self.uc_flags == other.uc_flags && + self.uc_link == other.uc_link && + self.uc_stack == other.uc_stack && + self.uc_mcontext == other.uc_mcontext && + self.uc_sigmask == other.uc_sigmask + // Ignore __private field + } +} +#[cfg(feature = "extra_traits")] +impl Eq for ucontext_t {} + pub const TIOCGSOFTCAR: ::c_ulong = 0x5419; pub const TIOCSSOFTCAR: ::c_ulong = 0x541A; diff --git a/src/unix/notbsd/linux/other/mod.rs b/src/unix/notbsd/linux/other/mod.rs index c1e339311d1db..6776728143a6c 100644 --- a/src/unix/notbsd/linux/other/mod.rs +++ b/src/unix/notbsd/linux/other/mod.rs @@ -29,42 +29,6 @@ s! { pub tv_usec: ::int32_t, } - pub struct utmpx { - pub ut_type: ::c_short, - pub ut_pid: ::pid_t, - pub ut_line: [::c_char; __UT_LINESIZE], - pub ut_id: [::c_char; 4], - - pub ut_user: [::c_char; __UT_NAMESIZE], - pub ut_host: [::c_char; __UT_HOSTSIZE], - pub ut_exit: __exit_status, - - #[cfg(any(target_arch = "aarch64", - target_arch = "sparc64", - all(target_pointer_width = "32", - not(target_arch = "x86_64"))))] - pub ut_session: ::c_long, - #[cfg(any(target_arch = "aarch64", - target_arch = "sparc64", - all(target_pointer_width = "32", - not(target_arch = "x86_64"))))] - pub ut_tv: ::timeval, - - #[cfg(not(any(target_arch = "aarch64", - target_arch = "sparc64", - all(target_pointer_width = "32", - not(target_arch = "x86_64")))))] - pub ut_session: ::int32_t, - #[cfg(not(any(target_arch = "aarch64", - target_arch = "sparc64", - all(target_pointer_width = "32", - not(target_arch = "x86_64")))))] - pub ut_tv: __timeval, - - pub ut_addr_v6: [::int32_t; 4], - __glibc_reserved: [::c_char; 20], - } - pub struct sigaction { pub sa_sigaction: ::sighandler_t, pub sa_mask: ::sigset_t, @@ -244,6 +208,63 @@ s! { } } +s_no_extra_traits! { + pub struct utmpx { + pub ut_type: ::c_short, + pub ut_pid: ::pid_t, + pub ut_line: [::c_char; __UT_LINESIZE], + pub ut_id: [::c_char; 4], + + pub ut_user: [::c_char; __UT_NAMESIZE], + pub ut_host: [::c_char; __UT_HOSTSIZE], + pub ut_exit: __exit_status, + + #[cfg(any(target_arch = "aarch64", + target_arch = "sparc64", + all(target_pointer_width = "32", + not(target_arch = "x86_64"))))] + pub ut_session: ::c_long, + #[cfg(any(target_arch = "aarch64", + target_arch = "sparc64", + all(target_pointer_width = "32", + not(target_arch = "x86_64"))))] + pub ut_tv: ::timeval, + + #[cfg(not(any(target_arch = "aarch64", + target_arch = "sparc64", + all(target_pointer_width = "32", + not(target_arch = "x86_64")))))] + pub ut_session: ::int32_t, + #[cfg(not(any(target_arch = "aarch64", + target_arch = "sparc64", + all(target_pointer_width = "32", + not(target_arch = "x86_64")))))] + pub ut_tv: __timeval, + + pub ut_addr_v6: [::int32_t; 4], + __glibc_reserved: [::c_char; 20], + } +} + +#[cfg(feature = "extra_traits")] +impl PartialEq for utmpx { + fn eq(&self, other: &utmpx) -> bool { + self.ut_type == other.ut_type && + 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_tv == other.ut_tv && + self.ut_addr_v6 == other.ut_addr_v6 && + self.__glibc_reserved == other.__glibc_reserved + } +} +#[cfg(feature = "extra_traits")] +impl Eq for utmpx {} + pub const __UT_LINESIZE: usize = 32; pub const __UT_NAMESIZE: usize = 32; pub const __UT_HOSTSIZE: usize = 256; diff --git a/src/unix/notbsd/mod.rs b/src/unix/notbsd/mod.rs index 668c25f7fee22..79b55792c0f8b 100644 --- a/src/unix/notbsd/mod.rs +++ b/src/unix/notbsd/mod.rs @@ -31,20 +31,6 @@ s! { pub sin6_scope_id: u32, } - pub struct sockaddr_un { - pub sun_family: sa_family_t, - pub sun_path: [::c_char; 108] - } - - pub struct sockaddr_storage { - pub ss_family: sa_family_t, - __ss_align: ::size_t, - #[cfg(target_pointer_width = "32")] - __ss_pad2: [u8; 128 - 2 * 4], - #[cfg(target_pointer_width = "64")] - __ss_pad2: [u8; 128 - 2 * 8], - } - pub struct addrinfo { pub ai_flags: ::c_int, pub ai_family: ::c_int, @@ -128,15 +114,6 @@ s! { pub u64: ::uint64_t, } - pub struct utsname { - pub sysname: [::c_char; 65], - pub nodename: [::c_char; 65], - pub release: [::c_char; 65], - pub version: [::c_char; 65], - pub machine: [::c_char; 65], - pub domainname: [::c_char; 65] - } - pub struct lconv { pub decimal_point: *mut ::c_char, pub thousands_sep: *mut ::c_char, @@ -230,6 +207,65 @@ s! { } } +s_no_extra_traits!{ + pub struct sockaddr_un { + pub sun_family: sa_family_t, + pub sun_path: [::c_char; 108] + } + + pub struct sockaddr_storage { + pub ss_family: sa_family_t, + __ss_align: ::size_t, + #[cfg(target_pointer_width = "32")] + __ss_pad2: [u8; 128 - 2 * 4], + #[cfg(target_pointer_width = "64")] + __ss_pad2: [u8; 128 - 2 * 8], + } + + pub struct utsname { + pub sysname: [::c_char; 65], + pub nodename: [::c_char; 65], + pub release: [::c_char; 65], + pub version: [::c_char; 65], + pub machine: [::c_char; 65], + pub domainname: [::c_char; 65] + } +} + +#[cfg(feature = "extra_traits")] +impl PartialEq for sockaddr_un { + fn eq(&self, other: &sockaddr_un) -> bool { + self.sun_family == other.sun_family && + self.sun_path.iter().zip(other.sun_path.iter()).all(|(a,b)| a == b) + } +} +#[cfg(feature = "extra_traits")] +impl Eq for sockaddr_un {} + +#[cfg(feature = "extra_traits")] +impl PartialEq for sockaddr_storage { + fn eq(&self, other: &sockaddr_storage) -> bool { + self.ss_family == other.ss_family && + self.__ss_pad2.iter().zip(other.__ss_pad2.iter()).all(|(a,b)| a == b) + } +} +#[cfg(feature = "extra_traits")] +impl Eq for sockaddr_storage {} + +#[cfg(feature = "extra_traits")] +impl PartialEq for utsname { + fn eq(&self, other: &utsname) -> bool { + self.sysname.iter().zip(other.sysname.iter()).all(|(a,b)| a == b) && + self.nodename.iter().zip(other.nodename.iter()).all(|(a,b)| a == b) && + self.release.iter().zip(other.release.iter()).all(|(a,b)| a == b) && + self.version.iter().zip(other.version.iter()).all(|(a,b)| a == b) && + self.machine.iter().zip(other.machine.iter()).all(|(a,b)| a == b) && + self.domainname.iter().zip(other.domainname.iter()).all(|(a,b)| a == b) + } +} +#[cfg(feature = "extra_traits")] +impl Eq for utsname {} + // intentionally not public, only used for fd_set cfg_if! { if #[cfg(target_pointer_width = "32")] {