Ctrl+C handling documentation
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
//! Provides handling for process interruption.
|
||||
//! There's no actual handling for Windows at the moment.
|
||||
#[cfg(unix)]
|
||||
mod unix;
|
||||
#[cfg(unix)]
|
||||
|
||||
@@ -1,23 +1,31 @@
|
||||
//! SIGINT handling in Unix systems.
|
||||
use lazy_static::lazy_static;
|
||||
use nix::sys::signal;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
lazy_static! {
|
||||
static ref RUNNING: AtomicBool = AtomicBool::new(true);
|
||||
/// A global variable telling whether the application has been interrupted.
|
||||
static ref INTERRUPTED: AtomicBool = AtomicBool::new(false);
|
||||
}
|
||||
|
||||
pub fn running() -> bool {
|
||||
RUNNING.load(Ordering::SeqCst)
|
||||
/// Tells whether the program has been interrupted
|
||||
pub fn interrupted() -> bool {
|
||||
INTERRUPTED.load(Ordering::SeqCst)
|
||||
}
|
||||
|
||||
pub fn set_running(value: bool) {
|
||||
RUNNING.store(value, Ordering::SeqCst)
|
||||
/// Clears the interrupted flag
|
||||
pub fn unset_interrupted() {
|
||||
debug_assert!(INTERRUPTED.load(Ordering::SeqCst));
|
||||
INTERRUPTED.store(false, Ordering::SeqCst)
|
||||
}
|
||||
|
||||
/// Handle SIGINT. Set the interruption flag.
|
||||
extern "C" fn handle_sigint(_: i32) {
|
||||
set_running(false);
|
||||
INTERRUPTED.store(true, Ordering::SeqCst)
|
||||
}
|
||||
|
||||
/// Set the necessary signal handlers.
|
||||
/// The function panics on failure.
|
||||
pub fn set_handler() {
|
||||
let sig_action = signal::SigAction::new(
|
||||
signal::SigHandler::Handler(handle_sigint),
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
pub fn running() -> bool {
|
||||
//! A stub for Ctrl + C handling.
|
||||
|
||||
pub fn interrupted() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
pub fn set_running(_value: bool) {}
|
||||
pub fn unset_interrupted() {}
|
||||
|
||||
pub fn set_handler() {}
|
||||
|
||||
10
src/main.rs
10
src/main.rs
@@ -31,13 +31,13 @@ where
|
||||
return Ok(Some((key, success)));
|
||||
}
|
||||
|
||||
let running = ctrlc::running();
|
||||
if !running {
|
||||
ctrlc::set_running(true);
|
||||
let interrupted = ctrlc::interrupted();
|
||||
if interrupted {
|
||||
ctrlc::unset_interrupted();
|
||||
}
|
||||
|
||||
let should_ask = !running || !no_retry;
|
||||
let should_retry = should_ask && should_retry(running).context(ErrorKind::Retry)?;
|
||||
let should_ask = interrupted || !no_retry;
|
||||
let should_retry = should_ask && should_retry(interrupted).context(ErrorKind::Retry)?;
|
||||
|
||||
if !should_retry {
|
||||
return Ok(Some((key, success)));
|
||||
|
||||
@@ -70,7 +70,7 @@ impl Terminal {
|
||||
.ok();
|
||||
}
|
||||
|
||||
fn should_retry(&mut self, running: bool) -> Result<bool, io::Error> {
|
||||
fn should_retry(&mut self, interrupted: bool) -> Result<bool, io::Error> {
|
||||
if self.width.is_none() {
|
||||
return Ok(false);
|
||||
}
|
||||
@@ -80,7 +80,7 @@ impl Terminal {
|
||||
"\n{}",
|
||||
style(format!(
|
||||
"Retry? [y/N] {}",
|
||||
if !running {
|
||||
if interrupted {
|
||||
"(Press Ctrl+C again to stop Topgrade) "
|
||||
} else {
|
||||
""
|
||||
@@ -111,8 +111,8 @@ impl Default for Terminal {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn should_retry(running: bool) -> Result<bool, io::Error> {
|
||||
TERMINAL.lock().unwrap().should_retry(running)
|
||||
pub fn should_retry(interrupted: bool) -> Result<bool, io::Error> {
|
||||
TERMINAL.lock().unwrap().should_retry(interrupted)
|
||||
}
|
||||
|
||||
pub fn print_separator<P: AsRef<str>>(message: P) {
|
||||
|
||||
Reference in New Issue
Block a user