use std::io;
#[cfg(target_os = "macos")]
#[repr(C)]
struct SigAction {
sa_handler: *const (),
sa_mask: u32,
sa_flags: i32,
}
#[cfg(target_os = "freebsd")]
#[repr(C)]
struct SigAction {
sa_handler: *const (),
sa_flags: i32,
sa_mask: [u8; 16],
}
#[cfg(target_os = "macos")]
const _: () = assert!(core::mem::size_of::<SigAction>() == 16);
#[cfg(target_os = "freebsd")]
const _: () = assert!(core::mem::size_of::<SigAction>() == 32);
#[cfg(target_os = "macos")]
const _: () = assert!(core::mem::offset_of!(SigAction, sa_handler) == 0);
#[cfg(target_os = "macos")]
const _: () = assert!(core::mem::offset_of!(SigAction, sa_mask) == 8);
#[cfg(target_os = "macos")]
const _: () = assert!(core::mem::offset_of!(SigAction, sa_flags) == 12);
#[cfg(target_os = "freebsd")]
const _: () = assert!(core::mem::offset_of!(SigAction, sa_handler) == 0);
#[cfg(target_os = "freebsd")]
const _: () = assert!(core::mem::offset_of!(SigAction, sa_flags) == 8);
#[cfg(target_os = "freebsd")]
const _: () = assert!(core::mem::offset_of!(SigAction, sa_mask) == 12);
#[cfg(target_os = "macos")]
const SA_RESTART: i32 = 0x0002;
#[cfg(target_os = "freebsd")]
const SA_RESTART: i32 = 0x0040;
extern "C" {
fn sigaction(signum: i32, act: *const SigAction, oldact: *mut SigAction) -> i32;
}
pub(super) unsafe fn install(handler: extern "C" fn(i32)) -> io::Result<()> {
const SIGINT: i32 = 2;
const SIGTERM: i32 = 15;
let mut act = std::mem::MaybeUninit::<SigAction>::zeroed();
unsafe {
(*act.as_mut_ptr()).sa_handler = handler as *const ();
(*act.as_mut_ptr()).sa_flags = SA_RESTART;
}
let act = unsafe { act.assume_init() };
for sig in [SIGINT, SIGTERM] {
let rc = unsafe { sigaction(sig, &act, std::ptr::null_mut()) };
if rc == -1 {
return Err(io::Error::last_os_error());
}
}
Ok(())
}