Skip to content

Commit 13d18ee

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 + 52d5741 commit 13d18ee

File tree

1 file changed

+172
-13
lines changed

1 file changed

+172
-13
lines changed

src/unix/solarish/mod.rs

Lines changed: 172 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,52 @@ 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+
// FIXME: The `si_pad` field in the 64-bit version of the struct is ignored
815+
// (for now) when doing comparisons.
816+
817+
let field_count = self.data_field_count();
818+
self.__data_pad[..field_count]
819+
.iter()
820+
.zip(other.__data_pad[..field_count].iter())
821+
.all(|(a, b)| a == b)
822+
} else {
823+
false
824+
}
787825
}
788826
}
789827
impl Eq for siginfo_t {}
@@ -793,7 +831,6 @@ cfg_if! {
793831
.field("si_signo", &self.si_signo)
794832
.field("si_code", &self.si_code)
795833
.field("si_errno", &self.si_errno)
796-
.field("si_addr", &self.si_addr)
797834
// FIXME: .field("__pad", &self.__pad)
798835
.finish()
799836
}
@@ -803,8 +840,12 @@ cfg_if! {
803840
self.si_signo.hash(state);
804841
self.si_code.hash(state);
805842
self.si_errno.hash(state);
806-
self.si_addr.hash(state);
807-
self.__pad.hash(state);
843+
844+
// FIXME: The `si_pad` field in the 64-bit version of the struct is ignored
845+
// (for now) when doing hashing.
846+
847+
let field_count = self.data_field_count();
848+
self.__data_pad[..field_count].hash(state)
808849
}
809850
}
810851

@@ -947,6 +988,116 @@ cfg_if! {
947988
}
948989
}
949990

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

10571208
pub const SIGCHLD: ::c_int = 18;
1209+
pub const SIGCLD: ::c_int = ::SIGCHLD;
10581210
pub const SIGBUS: ::c_int = 10;
10591211
pub const SIGINFO: ::c_int = 41;
10601212
pub const SIG_BLOCK: ::c_int = 1;
@@ -1065,6 +1217,13 @@ pub const SIGEV_NONE: ::c_int = 1;
10651217
pub const SIGEV_SIGNAL: ::c_int = 2;
10661218
pub const SIGEV_THREAD: ::c_int = 3;
10671219

1220+
pub const CLD_EXITED: ::c_int = 1;
1221+
pub const CLD_KILLED: ::c_int = 2;
1222+
pub const CLD_DUMPED: ::c_int = 3;
1223+
pub const CLD_TRAPPED: ::c_int = 4;
1224+
pub const CLD_STOPPED: ::c_int = 5;
1225+
pub const CLD_CONTINUED: ::c_int = 6;
1226+
10681227
pub const IP_RECVDSTADDR: ::c_int = 0x7;
10691228
pub const IP_SEC_OPT: ::c_int = 0x22;
10701229

0 commit comments

Comments
 (0)