2018-12-31 14:07:55 +02:00
|
|
|
//! SIGINT handling in Unix systems.
|
2018-11-18 11:52:37 +02:00
|
|
|
use lazy_static::lazy_static;
|
2018-10-17 14:07:58 +03:00
|
|
|
use nix::sys::signal;
|
|
|
|
|
use std::sync::atomic::{AtomicBool, Ordering};
|
|
|
|
|
|
|
|
|
|
lazy_static! {
|
2018-12-31 14:07:55 +02:00
|
|
|
/// A global variable telling whether the application has been interrupted.
|
|
|
|
|
static ref INTERRUPTED: AtomicBool = AtomicBool::new(false);
|
2018-10-17 14:07:58 +03:00
|
|
|
}
|
|
|
|
|
|
2018-12-31 14:07:55 +02:00
|
|
|
/// Tells whether the program has been interrupted
|
|
|
|
|
pub fn interrupted() -> bool {
|
|
|
|
|
INTERRUPTED.load(Ordering::SeqCst)
|
2018-10-17 14:07:58 +03:00
|
|
|
}
|
|
|
|
|
|
2018-12-31 14:07:55 +02:00
|
|
|
/// Clears the interrupted flag
|
|
|
|
|
pub fn unset_interrupted() {
|
|
|
|
|
debug_assert!(INTERRUPTED.load(Ordering::SeqCst));
|
|
|
|
|
INTERRUPTED.store(false, Ordering::SeqCst)
|
2018-10-17 14:07:58 +03:00
|
|
|
}
|
|
|
|
|
|
2018-12-31 14:07:55 +02:00
|
|
|
/// Handle SIGINT. Set the interruption flag.
|
2018-10-17 14:07:58 +03:00
|
|
|
extern "C" fn handle_sigint(_: i32) {
|
2018-12-31 14:07:55 +02:00
|
|
|
INTERRUPTED.store(true, Ordering::SeqCst)
|
2018-10-17 14:07:58 +03:00
|
|
|
}
|
|
|
|
|
|
2018-12-31 14:07:55 +02:00
|
|
|
/// Set the necessary signal handlers.
|
|
|
|
|
/// The function panics on failure.
|
2018-10-17 14:07:58 +03:00
|
|
|
pub fn set_handler() {
|
|
|
|
|
let sig_action = signal::SigAction::new(
|
|
|
|
|
signal::SigHandler::Handler(handle_sigint),
|
|
|
|
|
signal::SaFlags::empty(),
|
|
|
|
|
signal::SigSet::empty(),
|
|
|
|
|
);
|
|
|
|
|
unsafe {
|
|
|
|
|
signal::sigaction(signal::SIGINT, &sig_action).unwrap();
|
|
|
|
|
}
|
|
|
|
|
}
|