From 79ae1217c2a1a220b1c3f39283ba1ab812350cdc Mon Sep 17 00:00:00 2001
From: Bryant Mairs <bryant@mai.rs>
Date: Mon, 21 Jan 2019 19:40:02 -0800
Subject: [PATCH] Implement Debug for all types

---
 README.md                                 |   4 +-
 src/macros.rs                             |   2 +-
 src/unix/bsd/apple/b32.rs                 |   9 ++
 src/unix/bsd/apple/b64.rs                 |   9 ++
 src/unix/bsd/apple/mod.rs                 | 114 ++++++++++++++++++++--
 src/unix/bsd/mod.rs                       |  22 +++++
 src/unix/notbsd/android/b64/mod.rs        |  31 ++++++
 src/unix/notbsd/android/mod.rs            |  64 ++++++++++++
 src/unix/notbsd/linux/mod.rs              |  48 +++++++++
 src/unix/notbsd/linux/musl/b32/x86.rs     |  13 +++
 src/unix/notbsd/linux/musl/b64/x86_64.rs  |  13 +++
 src/unix/notbsd/linux/musl/mod.rs         |  21 ++++
 src/unix/notbsd/linux/other/b32/x86.rs    |  33 +++++++
 src/unix/notbsd/linux/other/b64/x86_64.rs |  30 ++++++
 src/unix/notbsd/linux/other/mod.rs        |  18 ++++
 src/unix/notbsd/linux/s390x.rs            |   8 ++
 src/unix/notbsd/mod.rs                    |  33 +++++++
 17 files changed, 463 insertions(+), 9 deletions(-)

diff --git a/README.md b/README.md
index ae45ce7f..4885cc9e 100644
--- a/README.md
+++ b/README.md
@@ -45,8 +45,8 @@ 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 (requires Rust 1.25 or newer):
+implemented for them. The additional traits of `Debug, `Eq`, and `PartialEq`
+can be enabled with the *extra_traits* feature (requires Rust 1.25 or newer):
 
 ```toml
 [dependencies]
diff --git a/src/macros.rs b/src/macros.rs
index 175c0512..3877797c 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -39,7 +39,7 @@ macro_rules! s {
         __item! {
             #[repr(C)]
             $(#[$attr])*
-            #[cfg_attr(feature = "extra_traits", derive(Eq, PartialEq))]
+            #[cfg_attr(feature = "extra_traits", derive(Debug, Eq, PartialEq))]
             pub $t $i { $($field)* }
         }
         impl ::dox::Copy for $i {}
diff --git a/src/unix/bsd/apple/b32.rs b/src/unix/bsd/apple/b32.rs
index 95dc962a..4950c197 100644
--- a/src/unix/bsd/apple/b32.rs
+++ b/src/unix/bsd/apple/b32.rs
@@ -64,6 +64,15 @@ impl PartialEq for pthread_attr_t {
 }
 #[cfg(feature = "extra_traits")]
 impl Eq for pthread_attr_t {}
+#[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for pthread_attr_t {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("pthread_attr_t")
+            .field("__sig", &self.__sig)
+            // FIXME: .field("__opaque", &self.__opaque)
+            .finish()
+    }
+}
 
 pub const __PTHREAD_MUTEX_SIZE__: usize = 40;
 pub const __PTHREAD_COND_SIZE__: usize = 24;
diff --git a/src/unix/bsd/apple/b64.rs b/src/unix/bsd/apple/b64.rs
index 0eb2d45c..c5f00384 100644
--- a/src/unix/bsd/apple/b64.rs
+++ b/src/unix/bsd/apple/b64.rs
@@ -69,6 +69,15 @@ impl PartialEq for pthread_attr_t {
 }
 #[cfg(feature = "extra_traits")]
 impl Eq for pthread_attr_t {}
+#[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for pthread_attr_t {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("pthread_attr_t")
+            .field("__sig", &self.__sig)
+            // FIXME: .field("__opaque", &self.__opaque)
+            .finish()
+    }
+}
 
 pub const __PTHREAD_MUTEX_SIZE__: usize = 56;
 pub const __PTHREAD_COND_SIZE__: usize = 40;
diff --git a/src/unix/bsd/apple/mod.rs b/src/unix/bsd/apple/mod.rs
index 80516388..16ce25f0 100644
--- a/src/unix/bsd/apple/mod.rs
+++ b/src/unix/bsd/apple/mod.rs
@@ -608,12 +608,6 @@ impl std::fmt::Debug for semun {
     }
 }
 #[cfg(feature = "extra_traits")]
-impl std::hash::Hash for semun {
-    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
-        unsafe { self.val.hash(state) };
-    }
-}
-#[cfg(feature = "extra_traits")]
 impl PartialEq for proc_threadinfo {
     fn eq(&self, other: &proc_threadinfo) -> bool {
         self.pth_user_time == other.pth_user_time
@@ -636,6 +630,24 @@ impl PartialEq for proc_threadinfo {
 #[cfg(feature = "extra_traits")]
 impl Eq for proc_threadinfo {}
 #[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for proc_threadinfo {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("proc_threadinfo")
+            .field("pth_user_time", &self.pth_user_time)
+            .field("pth_system_time", &self.pth_system_time)
+            .field("pth_cpu_usage", &self.pth_cpu_usage)
+            .field("pth_policy", &self.pth_policy)
+            .field("pth_run_state", &self.pth_run_state)
+            .field("pth_flags", &self.pth_flags)
+            .field("pth_sleep_time", &self.pth_sleep_time)
+            .field("pth_curpri", &self.pth_curpri)
+            .field("pth_priority", &self.pth_priority)
+            .field("pth_maxpriority", &self.pth_maxpriority)
+            // FIXME: .field("pth_name", &self.pth_name)
+            .finish()
+    }
+}
+#[cfg(feature = "extra_traits")]
 impl PartialEq for statfs {
     fn eq(&self, other: &statfs) -> bool {
         self.f_bsize == other.f_bsize
@@ -667,6 +679,29 @@ impl PartialEq for statfs {
 #[cfg(feature = "extra_traits")]
 impl Eq for statfs {}
 #[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for statfs {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("statfs")
+            .field("f_bsize", &self.f_bsize)
+            .field("f_iosize", &self.f_iosize)
+            .field("f_blocks", &self.f_blocks)
+            .field("f_bfree", &self.f_bfree)
+            .field("f_bavail", &self.f_bavail)
+            .field("f_files", &self.f_files)
+            .field("f_ffree", &self.f_ffree)
+            .field("f_fsid", &self.f_fsid)
+            .field("f_owner", &self.f_owner)
+            .field("f_flags", &self.f_flags)
+            .field("f_fssubtype", &self.f_fssubtype)
+            .field("f_fstypename", &self.f_fstypename)
+            .field("f_type", &self.f_type)
+            // FIXME: .field("f_mntonname", &self.f_mntonname)
+            // FIXME: .field("f_mntfromname", &self.f_mntfromname)
+            .field("f_reserved", &self.f_reserved)
+            .finish()
+    }
+}
+#[cfg(feature = "extra_traits")]
 impl PartialEq for dirent {
     fn eq(&self, other: &dirent) -> bool {
         self.d_ino == other.d_ino
@@ -684,6 +719,19 @@ impl PartialEq for dirent {
 #[cfg(feature = "extra_traits")]
 impl Eq for dirent {}
 #[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for dirent {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("dirent")
+            .field("d_ino", &self.d_ino)
+            .field("d_seekoff", &self.d_seekoff)
+            .field("d_reclen", &self.d_reclen)
+            .field("d_namlen", &self.d_namlen)
+            .field("d_type", &self.d_type)
+            // FIXME: .field("d_name", &self.d_name)
+            .finish()
+    }
+}
+#[cfg(feature = "extra_traits")]
 impl PartialEq for pthread_rwlock_t {
     fn eq(&self, other: &pthread_rwlock_t) -> bool {
         self.__sig == other.__sig
@@ -697,6 +745,15 @@ impl PartialEq for pthread_rwlock_t {
 #[cfg(feature = "extra_traits")]
 impl Eq for pthread_rwlock_t {}
 #[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for pthread_rwlock_t {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("pthread_rwlock_t")
+            .field("__sig", &self.__sig)
+            // FIXME: .field("__opaque", &self.__opaque)
+            .finish()
+    }
+}
+#[cfg(feature = "extra_traits")]
 impl PartialEq for pthread_mutex_t {
     fn eq(&self, other: &pthread_mutex_t) -> bool {
         self.__sig == other.__sig
@@ -710,6 +767,15 @@ impl PartialEq for pthread_mutex_t {
 #[cfg(feature = "extra_traits")]
 impl Eq for pthread_mutex_t {}
 #[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for pthread_mutex_t {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("pthread_mutex_t")
+            .field("__sig", &self.__sig)
+            // FIXME: .field("__opaque", &self.__opaque)
+            .finish()
+    }
+}
+#[cfg(feature = "extra_traits")]
 impl PartialEq for pthread_cond_t {
     fn eq(&self, other: &pthread_cond_t) -> bool {
         self.__sig == other.__sig
@@ -723,6 +789,15 @@ impl PartialEq for pthread_cond_t {
 #[cfg(feature = "extra_traits")]
 impl Eq for pthread_cond_t {}
 #[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for pthread_cond_t {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("pthread_cond_t")
+            .field("__sig", &self.__sig)
+            // FIXME: .field("__opaque", &self.__opaque)
+            .finish()
+    }
+}
+#[cfg(feature = "extra_traits")]
 impl PartialEq for sockaddr_storage {
     fn eq(&self, other: &sockaddr_storage) -> bool {
         self.ss_len == other.ss_len
@@ -743,6 +818,18 @@ impl PartialEq for sockaddr_storage {
 #[cfg(feature = "extra_traits")]
 impl Eq for sockaddr_storage {}
 #[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for sockaddr_storage {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("sockaddr_storage")
+            .field("ss_len", &self.ss_len)
+            .field("ss_family", &self.ss_family)
+            .field("__ss_pad1", &self.__ss_pad1)
+            .field("__ss_align", &self.__ss_align)
+            // FIXME: .field("__ss_pad2", &self.__ss_pad2)
+            .finish()
+    }
+}
+#[cfg(feature = "extra_traits")]
 impl PartialEq for utmpx {
     fn eq(&self, other: &utmpx) -> bool {
         self.ut_user
@@ -764,6 +851,21 @@ impl PartialEq for utmpx {
 }
 #[cfg(feature = "extra_traits")]
 impl Eq for utmpx {}
+#[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for utmpx {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("utmpx")
+            // FIXME: .field("ut_user", &self.ut_user)
+            .field("ut_id", &self.ut_id)
+            .field("ut_line", &self.ut_line)
+            .field("ut_pid", &self.ut_pid)
+            .field("ut_type", &self.ut_type)
+            .field("ut_tv", &self.ut_tv)
+            // FIXME: .field("ut_host", &self.ut_host)
+            .field("ut_pad", &self.ut_pad)
+            .finish()
+    }
+}
 
 pub const _UTX_USERSIZE: usize = 256;
 pub const _UTX_LINESIZE: usize = 32;
diff --git a/src/unix/bsd/mod.rs b/src/unix/bsd/mod.rs
index 63bfe958..74bbaf75 100644
--- a/src/unix/bsd/mod.rs
+++ b/src/unix/bsd/mod.rs
@@ -152,6 +152,16 @@ impl PartialEq for sockaddr_un {
 #[cfg(feature = "extra_traits")]
 impl Eq for sockaddr_un {}
 #[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for sockaddr_un {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("sockaddr_un")
+            .field("sun_len", &self.sun_len)
+            .field("sun_family", &self.sun_family)
+            // FIXME: .field("sun_path", &self.sun_path)
+            .finish()
+    }
+}
+#[cfg(feature = "extra_traits")]
 impl PartialEq for utsname {
     fn eq(&self, other: &utsname) -> bool {
         self.sysname
@@ -182,6 +192,18 @@ impl PartialEq for utsname {
 }
 #[cfg(feature = "extra_traits")]
 impl Eq for utsname {}
+#[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for utsname {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("utsname")
+            // FIXME: .field("sysname", &self.sysname)
+            // FIXME: .field("nodename", &self.nodename)
+            // FIXME: .field("release", &self.release)
+            // FIXME: .field("version", &self.version)
+            // FIXME: .field("machine", &self.machine)
+            .finish()
+    }
+}
 
 pub const LC_ALL: ::c_int = 0;
 pub const LC_COLLATE: ::c_int = 1;
diff --git a/src/unix/notbsd/android/b64/mod.rs b/src/unix/notbsd/android/b64/mod.rs
index b57e7bdc..c5a6a79e 100644
--- a/src/unix/notbsd/android/b64/mod.rs
+++ b/src/unix/notbsd/android/b64/mod.rs
@@ -141,6 +141,15 @@ impl PartialEq for pthread_mutex_t {
 #[cfg(feature = "extra_traits")]
 impl Eq for pthread_mutex_t {}
 #[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for pthread_mutex_t {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("pthread_mutex_t")
+            .field("value", &self.value)
+            // FIXME: .field("__reserved", &self.__reserved)
+            .finish()
+    }
+}
+#[cfg(feature = "extra_traits")]
 impl PartialEq for pthread_cond_t {
     fn eq(&self, other: &pthread_cond_t) -> bool {
         self.value == other.value
@@ -154,6 +163,15 @@ impl PartialEq for pthread_cond_t {
 #[cfg(feature = "extra_traits")]
 impl Eq for pthread_cond_t {}
 #[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for pthread_cond_t {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("pthread_cond_t")
+            .field("value", &self.value)
+            // FIXME: .field("__reserved", &self.__reserved)
+            .finish()
+    }
+}
+#[cfg(feature = "extra_traits")]
 impl PartialEq for pthread_rwlock_t {
     fn eq(&self, other: &pthread_rwlock_t) -> bool {
         self.numLocks == other.numLocks
@@ -170,6 +188,19 @@ impl PartialEq for pthread_rwlock_t {
 }
 #[cfg(feature = "extra_traits")]
 impl Eq for pthread_rwlock_t {}
+#[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for pthread_rwlock_t {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("pthread_rwlock_t")
+            .field("numLocks", &self.numLocks)
+            .field("writerThreadId", &self.writerThreadId)
+            .field("pendingReaders", &self.pendingReaders)
+            .field("pendingWriters", &self.pendingWriters)
+            .field("attr", &self.attr)
+            // FIXME: .field("__reserved", &self.__reserved)
+            .finish()
+    }
+}
 
 pub const RTLD_GLOBAL: ::c_int = 0x00100;
 pub const RTLD_NOW: ::c_int = 2;
diff --git a/src/unix/notbsd/android/mod.rs b/src/unix/notbsd/android/mod.rs
index 5345be0e..99faaef6 100644
--- a/src/unix/notbsd/android/mod.rs
+++ b/src/unix/notbsd/android/mod.rs
@@ -257,6 +257,18 @@ impl PartialEq for dirent {
 #[cfg(feature = "extra_traits")]
 impl Eq for dirent {}
 #[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for dirent {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("dirent")
+            .field("d_ino", &self.d_ino)
+            .field("d_off", &self.d_off)
+            .field("d_reclen", &self.d_reclen)
+            .field("d_type", &self.d_type)
+            .field("d_name", &self.d_name)
+            .finish()
+    }
+}
+#[cfg(feature = "extra_traits")]
 impl PartialEq for dirent64 {
     fn eq(&self, other: &dirent64) -> bool {
         self.d_ino == other.d_ino
@@ -273,6 +285,18 @@ impl PartialEq for dirent64 {
 #[cfg(feature = "extra_traits")]
 impl Eq for dirent64 {}
 #[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for dirent64 {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("dirent64")
+            .field("d_ino", &self.d_ino)
+            .field("d_off", &self.d_off)
+            .field("d_reclen", &self.d_reclen)
+            .field("d_type", &self.d_type)
+            .field("d_name", &self.d_name)
+            .finish()
+    }
+}
+#[cfg(feature = "extra_traits")]
 impl PartialEq for siginfo_t {
     fn eq(&self, other: &siginfo_t) -> bool {
         self.si_signo == other.si_signo
@@ -285,6 +309,18 @@ impl PartialEq for siginfo_t {
 #[cfg(feature = "extra_traits")]
 impl Eq for siginfo_t {}
 #[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for siginfo_t {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("siginfo_t")
+            .field("si_signo", &self.si_signo)
+            .field("si_errno", &self.si_errno)
+            .field("si_code", &self.si_code)
+            // Ignore _pad
+            // Ignore _align
+            .finish()
+    }
+}
+#[cfg(feature = "extra_traits")]
 impl PartialEq for lastlog {
     fn eq(&self, other: &lastlog) -> bool {
         self.ll_time == other.ll_time
@@ -303,6 +339,16 @@ impl PartialEq for lastlog {
 #[cfg(feature = "extra_traits")]
 impl Eq for lastlog {}
 #[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for lastlog {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("lastlog")
+            .field("ll_time", &self.ll_time)
+            .field("ll_line", &self.ll_line)
+            .field("ll_host", &self.ll_host)
+            .finish()
+    }
+}
+#[cfg(feature = "extra_traits")]
 impl PartialEq for utmp {
     fn eq(&self, other: &utmp) -> bool {
         self.ut_type == other.ut_type
@@ -332,6 +378,24 @@ impl PartialEq for utmp {
 }
 #[cfg(feature = "extra_traits")]
 impl Eq for utmp {}
+#[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for utmp {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("utmp")
+            .field("ut_type", &self.ut_type)
+            .field("ut_pid", &self.ut_pid)
+            .field("ut_line", &self.ut_line)
+            .field("ut_id", &self.ut_id)
+            .field("ut_user", &self.ut_user)
+            .field("ut_host", &self.ut_host)
+            .field("ut_exit", &self.ut_exit)
+            .field("ut_session", &self.ut_session)
+            .field("ut_tv", &self.ut_tv)
+            .field("ut_addr_v6", &self.ut_addr_v6)
+            .field("unused", &self.unused)
+            .finish()
+    }
+}
 
 pub const O_TRUNC: ::c_int = 512;
 pub const O_CLOEXEC: ::c_int = 0x80000;
diff --git a/src/unix/notbsd/linux/mod.rs b/src/unix/notbsd/linux/mod.rs
index bedcef2a..b0eac45b 100644
--- a/src/unix/notbsd/linux/mod.rs
+++ b/src/unix/notbsd/linux/mod.rs
@@ -675,6 +675,18 @@ impl PartialEq for dirent {
 }
 #[cfg(feature = "extra_traits")]
 impl Eq for dirent {}
+#[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for dirent {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("dirent")
+            .field("d_ino", &self.d_ino)
+            .field("d_off", &self.d_off)
+            .field("d_reclen", &self.d_reclen)
+            .field("d_type", &self.d_type)
+            // FIXME: .field("d_name", &self.d_name)
+            .finish()
+    }
+}
 
 #[cfg(feature = "extra_traits")]
 impl PartialEq for dirent64 {
@@ -692,6 +704,18 @@ impl PartialEq for dirent64 {
 }
 #[cfg(feature = "extra_traits")]
 impl Eq for dirent64 {}
+#[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for dirent64 {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("dirent64")
+            .field("d_ino", &self.d_ino)
+            .field("d_off", &self.d_off)
+            .field("d_reclen", &self.d_reclen)
+            .field("d_type", &self.d_type)
+            // FIXME: .field("d_name", &self.d_name)
+            .finish()
+    }
+}
 
 #[cfg(feature = "extra_traits")]
 impl PartialEq for pthread_cond_t {
@@ -701,6 +725,14 @@ impl PartialEq for pthread_cond_t {
 }
 #[cfg(feature = "extra_traits")]
 impl Eq for pthread_cond_t {}
+#[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for pthread_cond_t {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("pthread_cond_t")
+            // FIXME: .field("size", &self.size)
+            .finish()
+    }
+}
 
 #[cfg(feature = "extra_traits")]
 impl PartialEq for pthread_mutex_t {
@@ -710,6 +742,14 @@ impl PartialEq for pthread_mutex_t {
 }
 #[cfg(feature = "extra_traits")]
 impl Eq for pthread_mutex_t {}
+#[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for pthread_mutex_t {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("pthread_mutex_t")
+            // FIXME: .field("size", &self.size)
+            .finish()
+    }
+}
 
 #[cfg(feature = "extra_traits")]
 impl PartialEq for pthread_rwlock_t {
@@ -719,6 +759,14 @@ impl PartialEq for pthread_rwlock_t {
 }
 #[cfg(feature = "extra_traits")]
 impl Eq for pthread_rwlock_t {}
+#[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for pthread_rwlock_t {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("pthread_rwlock_t")
+            // FIXME: .field("size", &self.size)
+            .finish()
+    }
+}
 
 pub const ABDAY_1: ::nl_item = 0x20000;
 pub const ABDAY_2: ::nl_item = 0x20001;
diff --git a/src/unix/notbsd/linux/musl/b32/x86.rs b/src/unix/notbsd/linux/musl/b32/x86.rs
index 222868e6..9b79356f 100644
--- a/src/unix/notbsd/linux/musl/b32/x86.rs
+++ b/src/unix/notbsd/linux/musl/b32/x86.rs
@@ -194,6 +194,19 @@ impl PartialEq for ucontext_t {
 }
 #[cfg(feature = "extra_traits")]
 impl Eq for ucontext_t {}
+#[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for ucontext_t {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("ucontext_t")
+            .field("uc_flags", &self.uc_flags)
+            .field("uc_link", &self.uc_link)
+            .field("uc_stack", &self.uc_stack)
+            .field("uc_mcontext", &self.uc_mcontext)
+            .field("uc_sigmask", &self.uc_sigmask)
+            // Ignore __private field
+            .finish()
+    }
+}
 
 pub const SIGSTKSZ: ::size_t = 8192;
 pub const MINSIGSTKSZ: ::size_t = 2048;
diff --git a/src/unix/notbsd/linux/musl/b64/x86_64.rs b/src/unix/notbsd/linux/musl/b64/x86_64.rs
index 1033e6c6..1679a3ab 100644
--- a/src/unix/notbsd/linux/musl/b64/x86_64.rs
+++ b/src/unix/notbsd/linux/musl/b64/x86_64.rs
@@ -92,6 +92,19 @@ impl PartialEq for ucontext_t {
 }
 #[cfg(feature = "extra_traits")]
 impl Eq for ucontext_t {}
+#[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for ucontext_t {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("ucontext_t")
+            .field("uc_flags", &self.uc_flags)
+            .field("uc_link", &self.uc_link)
+            .field("uc_stack", &self.uc_stack)
+            .field("uc_mcontext", &self.uc_mcontext)
+            .field("uc_sigmask", &self.uc_sigmask)
+            // Ignore __private field
+            .finish()
+    }
+}
 
 // Syscall table
 
diff --git a/src/unix/notbsd/linux/musl/mod.rs b/src/unix/notbsd/linux/musl/mod.rs
index 7eb52fc2..6d1a0a13 100644
--- a/src/unix/notbsd/linux/musl/mod.rs
+++ b/src/unix/notbsd/linux/musl/mod.rs
@@ -120,6 +120,27 @@ impl PartialEq for sysinfo {
 }
 #[cfg(feature = "extra_traits")]
 impl Eq for sysinfo {}
+#[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for sysinfo {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("sysinfo")
+            .field("uptime", &self.uptime)
+            .field("loads", &self.loads)
+            .field("totalram", &self.totalram)
+            .field("freeram", &self.freeram)
+            .field("sharedram", &self.sharedram)
+            .field("bufferram", &self.bufferram)
+            .field("totalswap", &self.totalswap)
+            .field("freeswap", &self.freeswap)
+            .field("procs", &self.procs)
+            .field("pad", &self.pad)
+            .field("totalhigh", &self.totalhigh)
+            .field("freehigh", &self.freehigh)
+            .field("mem_unit", &self.mem_unit)
+            // FIXME: .field("__reserved", &self.__reserved)
+            .finish()
+    }
+}
 
 pub const SFD_CLOEXEC: ::c_int = 0x080000;
 
diff --git a/src/unix/notbsd/linux/other/b32/x86.rs b/src/unix/notbsd/linux/other/b32/x86.rs
index 2d262b3b..d3186c0f 100644
--- a/src/unix/notbsd/linux/other/b32/x86.rs
+++ b/src/unix/notbsd/linux/other/b32/x86.rs
@@ -236,6 +236,26 @@ impl PartialEq for user_fpxregs_struct {
 #[cfg(feature = "extra_traits")]
 impl Eq for user_fpxregs_struct {}
 #[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for user_fpxregs_struct {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("user_fpxregs_struct")
+            .field("cwd", &self.cwd)
+            .field("swd", &self.swd)
+            .field("twd", &self.twd)
+            .field("fop", &self.fop)
+            .field("fip", &self.fip)
+            .field("fcs", &self.fcs)
+            .field("foo", &self.foo)
+            .field("fos", &self.fos)
+            .field("mxcsr", &self.mxcsr)
+            // Ignore __reserved field
+            .field("st_space", &self.st_space)
+            .field("xmm_space", &self.xmm_space)
+            // Ignore padding field
+            .finish()
+    }
+}
+#[cfg(feature = "extra_traits")]
 impl PartialEq for ucontext_t {
     fn eq(&self, other: &ucontext_t) -> bool {
         self.uc_flags == other.uc_flags
@@ -248,6 +268,19 @@ impl PartialEq for ucontext_t {
 }
 #[cfg(feature = "extra_traits")]
 impl Eq for ucontext_t {}
+#[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for ucontext_t {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("ucontext_t")
+            .field("uc_flags", &self.uc_flags)
+            .field("uc_link", &self.uc_link)
+            .field("uc_stack", &self.uc_stack)
+            .field("uc_mcontext", &self.uc_mcontext)
+            .field("uc_sigmask", &self.uc_sigmask)
+            // Ignore __private field
+            .finish()
+    }
+}
 
 pub const O_DIRECT: ::c_int = 0x4000;
 pub const O_DIRECTORY: ::c_int = 0x10000;
diff --git a/src/unix/notbsd/linux/other/b64/x86_64.rs b/src/unix/notbsd/linux/other/b64/x86_64.rs
index 2257ea42..02745b90 100644
--- a/src/unix/notbsd/linux/other/b64/x86_64.rs
+++ b/src/unix/notbsd/linux/other/b64/x86_64.rs
@@ -256,6 +256,23 @@ impl PartialEq for user_fpregs_struct {
 }
 #[cfg(feature = "extra_traits")]
 impl Eq for user_fpregs_struct {}
+#[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for user_fpregs_struct {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("user_fpregs_struct")
+            .field("cwd", &self.cwd)
+            .field("ftw", &self.ftw)
+            .field("fop", &self.fop)
+            .field("rip", &self.rip)
+            .field("rdp", &self.rdp)
+            .field("mxcsr", &self.mxcsr)
+            .field("mxcr_mask", &self.mxcr_mask)
+            .field("st_space", &self.st_space)
+            // FIXME: .field("xmm_space", &self.xmm_space)
+            // Ignore padding field
+            .finish()
+    }
+}
 
 #[cfg(feature = "extra_traits")]
 impl PartialEq for ucontext_t {
@@ -270,6 +287,19 @@ impl PartialEq for ucontext_t {
 }
 #[cfg(feature = "extra_traits")]
 impl Eq for ucontext_t {}
+#[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for ucontext_t {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("ucontext_t")
+            .field("uc_flags", &self.uc_flags)
+            .field("uc_link", &self.uc_link)
+            .field("uc_stack", &self.uc_stack)
+            .field("uc_mcontext", &self.uc_mcontext)
+            .field("uc_sigmask", &self.uc_sigmask)
+            // Ignore __private field
+            .finish()
+    }
+}
 
 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 67ddda30..fa0e39ba 100644
--- a/src/unix/notbsd/linux/other/mod.rs
+++ b/src/unix/notbsd/linux/other/mod.rs
@@ -268,6 +268,24 @@ impl PartialEq for utmpx {
 }
 #[cfg(feature = "extra_traits")]
 impl Eq for utmpx {}
+#[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for utmpx {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("utmpx")
+            .field("ut_type", &self.ut_type)
+            .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_tv", &self.ut_tv)
+            .field("ut_addr_v6", &self.ut_addr_v6)
+            .field("__glibc_reserved", &self.__glibc_reserved)
+            .finish()
+    }
+}
 
 pub const __UT_LINESIZE: usize = 32;
 pub const __UT_NAMESIZE: usize = 32;
diff --git a/src/unix/notbsd/linux/s390x.rs b/src/unix/notbsd/linux/s390x.rs
index 6f21e947..8a6b88a8 100644
--- a/src/unix/notbsd/linux/s390x.rs
+++ b/src/unix/notbsd/linux/s390x.rs
@@ -344,6 +344,14 @@ impl PartialEq for fpreg_t {
 }
 #[cfg(feature = "extra_traits")]
 impl Eq for fpreg_t {}
+#[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for fpreg_t {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("fpreg_t")
+            .field("d", &self.d)
+            .finish()
+    }
+}
 
 pub const SFD_CLOEXEC: ::c_int = 0x080000;
 
diff --git a/src/unix/notbsd/mod.rs b/src/unix/notbsd/mod.rs
index 9caa2866..cd613d44 100644
--- a/src/unix/notbsd/mod.rs
+++ b/src/unix/notbsd/mod.rs
@@ -245,6 +245,15 @@ impl PartialEq for sockaddr_un {
 }
 #[cfg(feature = "extra_traits")]
 impl Eq for sockaddr_un {}
+#[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for sockaddr_un {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("sockaddr_un")
+            .field("sun_family", &self.sun_family)
+            // FIXME: .field("sun_path", &self.sun_path)
+            .finish()
+    }
+}
 
 #[cfg(feature = "extra_traits")]
 impl PartialEq for sockaddr_storage {
@@ -259,6 +268,16 @@ impl PartialEq for sockaddr_storage {
 }
 #[cfg(feature = "extra_traits")]
 impl Eq for sockaddr_storage {}
+#[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for sockaddr_storage {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("sockaddr_storage")
+            .field("ss_family", &self.ss_family)
+            .field("__ss_align", &self.__ss_align)
+            // FIXME: .field("__ss_pad2", &self.__ss_pad2)
+            .finish()
+    }
+}
 
 #[cfg(feature = "extra_traits")]
 impl PartialEq for utsname {
@@ -296,6 +315,20 @@ impl PartialEq for utsname {
 }
 #[cfg(feature = "extra_traits")]
 impl Eq for utsname {}
+#[cfg(feature = "extra_traits")]
+impl std::fmt::Debug for utsname {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("utsname")
+            // FIXME: .field("sysname", &self.sysname)
+            // FIXME: .field("nodename", &self.nodename)
+            // FIXME: .field("release", &self.release)
+            // FIXME: .field("version", &self.version)
+            // FIXME: .field("machine", &self.machine)
+            // FIXME: .field("domainname", &self.domainname)
+            .finish()
+    }
+}
+
 // intentionally not public, only used for fd_set
 cfg_if! {
     if #[cfg(target_pointer_width = "32")] {
-- 
GitLab