use std::sync::atomic::{AtomicBool, AtomicI32, Ordering};
static CAUGHT: AtomicI32 = AtomicI32::new(0);
static SIGNALLED: AtomicBool = AtomicBool::new(false);
extern "C" fn note(sig: libc::c_int) {
if SIGNALLED.swap(true, Ordering::SeqCst) {
unsafe { libc::_exit(128 + sig) };
}
let _ = CAUGHT.compare_exchange(0, sig, Ordering::SeqCst, Ordering::SeqCst);
if sig == libc::SIGHUP {
unsafe {
let mut fds = [0; 2];
if libc::pipe2(fds.as_mut_ptr(), libc::O_NONBLOCK | libc::O_CLOEXEC) == 0 {
libc::dup2(fds[0], 0);
}
}
}
}
pub fn install() {
for sig in [libc::SIGTERM, libc::SIGHUP] {
unsafe {
let mut act: libc::sigaction = std::mem::zeroed();
act.sa_sigaction = note as extern "C" fn(libc::c_int) as libc::sighandler_t;
libc::sigemptyset(&mut act.sa_mask);
libc::sigaction(sig, &act, std::ptr::null_mut());
}
}
}
pub fn caught() -> bool {
CAUGHT.load(Ordering::SeqCst) != 0
}
pub fn hung_up() -> bool {
CAUGHT.load(Ordering::SeqCst) == libc::SIGHUP
}