From 13d0cdb68f839a2c13b739f9fe3ed87ebc86c049 Mon Sep 17 00:00:00 2001 From: Josh Triplett <josh@joshtriplett.org> Date: Sun, 9 Aug 2020 15:10:20 -0700 Subject: [PATCH] Expose si_pid, si_uid, and si_status from siginfo_t as functions On Linux, siginfo_t cannot expose these fields directly due to https://github.com/rust-lang/libc/issues/716 , so expose them as functions, just like si_addr and si_value. In order to get alignment correct on both 32-bit and 64-bit architectures, define an sifields union that includes a pointer field, to ensure that it has the same alignment as a pointer. --- src/unix/bsd/apple/mod.rs | 8 +++++ src/unix/bsd/freebsdlike/mod.rs | 8 +++++ src/unix/haiku/mod.rs | 14 ++++++++ src/unix/linux_like/linux/gnu/mod.rs | 49 ++++++++++++++++++++++++++++ src/vxworks/mod.rs | 18 ++++++++++ 5 files changed, 97 insertions(+) diff --git a/src/unix/bsd/apple/mod.rs b/src/unix/bsd/apple/mod.rs index f1309747..f56ee02b 100644 --- a/src/unix/bsd/apple/mod.rs +++ b/src/unix/bsd/apple/mod.rs @@ -680,6 +680,14 @@ impl siginfo_t { (*(self as *const siginfo_t as *const siginfo_timer)).si_value } + + pub unsafe fn si_pid(&self) -> ::pid_t { + self.si_pid + } + + pub unsafe fn si_uid(&self) -> ::uid_t { + self.si_uid + } } cfg_if! { diff --git a/src/unix/bsd/freebsdlike/mod.rs b/src/unix/bsd/freebsdlike/mod.rs index b75c1a8e..e9f70579 100644 --- a/src/unix/bsd/freebsdlike/mod.rs +++ b/src/unix/bsd/freebsdlike/mod.rs @@ -31,6 +31,14 @@ impl siginfo_t { pub unsafe fn si_value(&self) -> ::sigval { self.si_value } + + pub unsafe fn si_pid(&self) -> ::pid_t { + self.si_pid + } + + pub unsafe fn si_uid(&self) -> ::uid_t { + self.si_uid + } } s! { diff --git a/src/unix/haiku/mod.rs b/src/unix/haiku/mod.rs index 27f88f15..adcac2e5 100644 --- a/src/unix/haiku/mod.rs +++ b/src/unix/haiku/mod.rs @@ -38,6 +38,20 @@ impl ::Clone for timezone { } } +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut ::c_void { + self.si_addr + } + + pub unsafe fn si_pid(&self) -> ::pid_t { + self.si_pid + } + + pub unsafe fn si_uid(&self) -> ::uid_t { + self.si_uid + } +} + s! { pub struct in_addr { pub s_addr: ::in_addr_t, diff --git a/src/unix/linux_like/linux/gnu/mod.rs b/src/unix/linux_like/linux/gnu/mod.rs index 44796c3e..982916a2 100644 --- a/src/unix/linux_like/linux/gnu/mod.rs +++ b/src/unix/linux_like/linux/gnu/mod.rs @@ -313,6 +313,55 @@ impl siginfo_t { } } +cfg_if! { + if #[cfg(libc_union)] { + // Internal, for casts to access union fields + #[repr(C)] + #[derive(Copy,Clone)] + struct sifields_sigchld { + si_pid: ::pid_t, + si_uid: ::uid_t, + si_status: ::c_int, + } + + // Internal, for casts to access union fields + #[repr(C)] + union sifields { + _align_pointer: *mut ::c_void, + sigchld: sifields_sigchld, + } + + // Internal, for casts to access union fields. Note that some variants + // of sifields start with a pointer, which makes the alignment of + // sifields vary on 32-bit and 64-bit architectures. + #[repr(C)] + struct siginfo_f { + _si_signo: ::c_int, + _si_errno: ::c_int, + _si_code: ::c_int, + sifields: sifields, + } + + impl siginfo_t { + unsafe fn sifields(&self) -> &sifields { + &(*(self as *const siginfo_t as *const siginfo_f)).sifields + } + + pub unsafe fn si_pid(&self) -> ::pid_t { + self.sifields().sigchld.si_pid + } + + pub unsafe fn si_uid(&self) -> ::uid_t { + self.sifields().sigchld.si_uid + } + + pub unsafe fn si_status(&self) -> ::c_int { + self.sifields().sigchld.si_status + } + } + } +} + s_no_extra_traits! { pub struct utmpx { pub ut_type: ::c_short, diff --git a/src/vxworks/mod.rs b/src/vxworks/mod.rs index 2ca38d5e..2a3ac7ff 100755 --- a/src/vxworks/mod.rs +++ b/src/vxworks/mod.rs @@ -112,6 +112,24 @@ impl ::Clone for _Vx_semaphore { } } +impl siginfo_t { + pub unsafe fn si_addr(&self) -> *mut ::c_void { + self.si_addr + } + + pub unsafe fn si_value(&self) -> ::sigval { + self.si_value + } + + pub unsafe fn si_pid(&self) -> ::pid_t { + self.si_pid + } + + pub unsafe fn si_uid(&self) -> ::uid_t { + self.si_uid + } +} + s! { // b_pthread_condattr_t.h pub struct pthread_condattr_t { -- GitLab