Skip to content

Commit 894646a

Browse files
committed
Auto merge of #2697 - pfmooney:illumos-siginfo, r=Amanieu
solarish: Expose siginfo_t data as functions This will bring illumos (and Solaris) functionality in line with the other UNIX (and UNIX-like) platforms, where unions often hamper access to those data fields.
2 parents 225ef2f + aa8f0f2 commit 894646a

File tree

1 file changed

+174
-13
lines changed

1 file changed

+174
-13
lines changed

src/unix/solarish/mod.rs

Lines changed: 174 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub type zoneid_t = ::c_int;
2828
pub type psetid_t = ::c_int;
2929
pub type processorid_t = ::c_int;
3030
pub type chipid_t = ::c_int;
31+
pub type ctid_t = ::id_t;
3132

3233
pub type suseconds_t = ::c_long;
3334
pub type off_t = ::c_long;
@@ -516,13 +517,15 @@ s_no_extra_traits! {
516517
__ss_pad2: [u8; 240],
517518
}
518519

520+
#[cfg_attr(all(target_pointer_width = "64", libc_align), repr(align(8)))]
519521
pub struct siginfo_t {
520522
pub si_signo: ::c_int,
521523
pub si_code: ::c_int,
522524
pub si_errno: ::c_int,
525+
#[cfg(target_pointer_width = "64")]
523526
pub si_pad: ::c_int,
524-
pub si_addr: *mut ::c_void,
525-
__pad: [u8; 232],
527+
528+
__data_pad: [::c_int; SIGINFO_DATA_SIZE],
526529
}
527530

528531
pub struct sockaddr_dl {
@@ -773,17 +776,54 @@ cfg_if! {
773776
}
774777
}
775778

779+
impl siginfo_t {
780+
/// The siginfo_t will have differing contents based on the delivered signal. Based on
781+
/// `si_signo`, this determines how many of the `c_int` pad fields contain valid data
782+
/// exposed by the C unions.
783+
///
784+
/// It is not yet exhausitive for the OS-defined types, and defaults to assuming the
785+
/// entire data pad area is "valid" for otherwise unrecognized signal numbers.
786+
fn data_field_count(&self) -> usize {
787+
match self.si_signo {
788+
::SIGSEGV | ::SIGBUS | ::SIGILL | ::SIGTRAP | ::SIGFPE => {
789+
::mem::size_of::<siginfo_fault>() / ::mem::size_of::<::c_int>()
790+
}
791+
::SIGCLD => ::mem::size_of::<siginfo_sigcld>() / ::mem::size_of::<::c_int>(),
792+
::SIGHUP
793+
| ::SIGINT
794+
| ::SIGQUIT
795+
| ::SIGABRT
796+
| ::SIGSYS
797+
| ::SIGPIPE
798+
| ::SIGALRM
799+
| ::SIGTERM
800+
| ::SIGUSR1
801+
| ::SIGUSR2
802+
| ::SIGPWR
803+
| ::SIGWINCH
804+
| ::SIGURG => ::mem::size_of::<siginfo_kill>() / ::mem::size_of::<::c_int>(),
805+
_ => SIGINFO_DATA_SIZE,
806+
}
807+
}
808+
}
776809
impl PartialEq for siginfo_t {
777810
fn eq(&self, other: &siginfo_t) -> bool {
778-
self.si_signo == other.si_signo
811+
if self.si_signo == other.si_signo
779812
&& self.si_code == other.si_code
780-
&& self.si_errno == other.si_errno
781-
&& self.si_addr == other.si_addr
782-
&& self
783-
.__pad
784-
.iter()
785-
.zip(other.__pad.iter())
786-
.all(|(a, b)| a == b)
813+
&& self.si_errno == other.si_errno {
814+
#[cfg(target_pointer_width = "64")]
815+
if self.si_pad != other.si_pad {
816+
return false;
817+
}
818+
819+
let field_count = self.data_field_count();
820+
self.__data_pad[..field_count]
821+
.iter()
822+
.zip(other.__data_pad[..field_count].iter())
823+
.all(|(a, b)| a == b)
824+
} else {
825+
false
826+
}
787827
}
788828
}
789829
impl Eq for siginfo_t {}
@@ -793,7 +833,6 @@ cfg_if! {
793833
.field("si_signo", &self.si_signo)
794834
.field("si_code", &self.si_code)
795835
.field("si_errno", &self.si_errno)
796-
.field("si_addr", &self.si_addr)
797836
// FIXME: .field("__pad", &self.__pad)
798837
.finish()
799838
}
@@ -803,8 +842,12 @@ cfg_if! {
803842
self.si_signo.hash(state);
804843
self.si_code.hash(state);
805844
self.si_errno.hash(state);
806-
self.si_addr.hash(state);
807-
self.__pad.hash(state);
845+
846+
#[cfg(target_pointer_width = "64")]
847+
self.si_pad.hash(state);
848+
849+
let field_count = self.data_field_count();
850+
self.__data_pad[..field_count].hash(state)
808851
}
809852
}
810853

@@ -947,6 +990,116 @@ cfg_if! {
947990
}
948991
}
949992

993+
cfg_if! {
994+
if #[cfg(target_pointer_width = "64")] {
995+
const SIGINFO_DATA_SIZE: usize = 60;
996+
} else {
997+
const SIGINFO_DATA_SIZE: usize = 29;
998+
}
999+
}
1000+
1001+
#[repr(C)]
1002+
struct siginfo_fault {
1003+
addr: *mut ::c_void,
1004+
trapno: ::c_int,
1005+
pc: *mut ::caddr_t,
1006+
}
1007+
impl Copy for siginfo_fault {}
1008+
impl Clone for siginfo_fault {
1009+
fn clone(&self) -> Self {
1010+
*self
1011+
}
1012+
}
1013+
1014+
#[repr(C)]
1015+
struct siginfo_cldval {
1016+
utime: ::clock_t,
1017+
status: ::c_int,
1018+
stime: ::clock_t,
1019+
}
1020+
impl Copy for siginfo_cldval {}
1021+
impl Clone for siginfo_cldval {
1022+
fn clone(&self) -> Self {
1023+
*self
1024+
}
1025+
}
1026+
1027+
#[repr(C)]
1028+
struct siginfo_killval {
1029+
uid: ::uid_t,
1030+
value: ::sigval,
1031+
// Pad out to match the SIGCLD value size
1032+
_pad: *mut ::c_void,
1033+
}
1034+
impl Copy for siginfo_killval {}
1035+
impl Clone for siginfo_killval {
1036+
fn clone(&self) -> Self {
1037+
*self
1038+
}
1039+
}
1040+
1041+
#[repr(C)]
1042+
struct siginfo_sigcld {
1043+
pid: ::pid_t,
1044+
val: siginfo_cldval,
1045+
ctid: ::ctid_t,
1046+
zoneid: ::zoneid_t,
1047+
}
1048+
impl Copy for siginfo_sigcld {}
1049+
impl Clone for siginfo_sigcld {
1050+
fn clone(&self) -> Self {
1051+
*self
1052+
}
1053+
}
1054+
1055+
#[repr(C)]
1056+
struct siginfo_kill {
1057+
pid: ::pid_t,
1058+
val: siginfo_killval,
1059+
ctid: ::ctid_t,
1060+
zoneid: ::zoneid_t,
1061+
}
1062+
impl Copy for siginfo_kill {}
1063+
impl Clone for siginfo_kill {
1064+
fn clone(&self) -> Self {
1065+
*self
1066+
}
1067+
}
1068+
1069+
impl siginfo_t {
1070+
unsafe fn sidata<T: Copy>(&self) -> T {
1071+
*((&self.__data_pad) as *const ::c_int as *const T)
1072+
}
1073+
pub unsafe fn si_addr(&self) -> *mut ::c_void {
1074+
let sifault: siginfo_fault = self.sidata();
1075+
sifault.addr
1076+
}
1077+
pub unsafe fn si_uid(&self) -> ::uid_t {
1078+
let kill: siginfo_kill = self.sidata();
1079+
kill.val.uid
1080+
}
1081+
pub unsafe fn si_value(&self) -> ::sigval {
1082+
let kill: siginfo_kill = self.sidata();
1083+
kill.val.value
1084+
}
1085+
pub unsafe fn si_pid(&self) -> ::pid_t {
1086+
let sigcld: siginfo_sigcld = self.sidata();
1087+
sigcld.pid
1088+
}
1089+
pub unsafe fn si_status(&self) -> ::c_int {
1090+
let sigcld: siginfo_sigcld = self.sidata();
1091+
sigcld.val.status
1092+
}
1093+
pub unsafe fn si_utime(&self) -> ::c_long {
1094+
let sigcld: siginfo_sigcld = self.sidata();
1095+
sigcld.val.utime
1096+
}
1097+
pub unsafe fn si_stime(&self) -> ::c_long {
1098+
let sigcld: siginfo_sigcld = self.sidata();
1099+
sigcld.val.stime
1100+
}
1101+
}
1102+
9501103
pub const LC_CTYPE: ::c_int = 0;
9511104
pub const LC_NUMERIC: ::c_int = 1;
9521105
pub const LC_TIME: ::c_int = 2;
@@ -1055,6 +1208,7 @@ pub const FIOSETOWN: ::c_int = 0x8004667c;
10551208
pub const FIOGETOWN: ::c_int = 0x4004667b;
10561209

10571210
pub const SIGCHLD: ::c_int = 18;
1211+
pub const SIGCLD: ::c_int = ::SIGCHLD;
10581212
pub const SIGBUS: ::c_int = 10;
10591213
pub const SIGINFO: ::c_int = 41;
10601214
pub const SIG_BLOCK: ::c_int = 1;
@@ -1065,6 +1219,13 @@ pub const SIGEV_NONE: ::c_int = 1;
10651219
pub const SIGEV_SIGNAL: ::c_int = 2;
10661220
pub const SIGEV_THREAD: ::c_int = 3;
10671221

1222+
pub const CLD_EXITED: ::c_int = 1;
1223+
pub const CLD_KILLED: ::c_int = 2;
1224+
pub const CLD_DUMPED: ::c_int = 3;
1225+
pub const CLD_TRAPPED: ::c_int = 4;
1226+
pub const CLD_STOPPED: ::c_int = 5;
1227+
pub const CLD_CONTINUED: ::c_int = 6;
1228+
10681229
pub const IP_RECVDSTADDR: ::c_int = 0x7;
10691230
pub const IP_SEC_OPT: ::c_int = 0x22;
10701231

0 commit comments

Comments
 (0)