in reverie-ptrace/src/timer.rs [625:671]
fn get_si_fd(signal: &libc::siginfo_t) -> libc::c_int {
// This almost certainly broken for anything other than linux (glibc?).
//
// The `libc` crate doesn't expose these fields properly, because the
// current version was released before union support, and `siginfo_t` is a
// messy enum/union, making this super fragile.
//
// `libc` has an accessor system in place, but only for a few particular
// signal types as of right now. We could submit a PR for SIGPOLL/SIGIO, but
// until then, this is copies the currently used accessor idea.
#[repr(C)]
#[derive(Copy, Clone)]
struct sifields_sigpoll {
si_band: libc::c_long,
si_fd: libc::c_int,
}
#[repr(C)]
union sifields {
_align_pointer: *mut libc::c_void,
sigpoll: sifields_sigpoll,
}
#[repr(C)]
struct siginfo_f {
_siginfo_base: [libc::c_int; 3],
sifields: sifields,
padding: [libc::c_int; 24],
}
// These compile to no-op or unconditional runtime panic, which is good,
// because code not using timers continues to work.
assert_eq!(
core::mem::size_of::<siginfo_f>(),
core::mem::size_of_val(signal),
);
assert_eq!(
core::mem::align_of::<siginfo_f>(),
core::mem::align_of_val(signal),
);
unsafe {
(*(signal as *const _ as *const siginfo_f))
.sifields
.sigpoll
.si_fd
}
}