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)]
|
#[cfg(unix)]
|
||||||
mod unix;
|
mod unix;
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
|
|||||||
@@ -1,23 +1,31 @@
|
|||||||
|
//! SIGINT handling in Unix systems.
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use nix::sys::signal;
|
use nix::sys::signal;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
lazy_static! {
|
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 {
|
/// Tells whether the program has been interrupted
|
||||||
RUNNING.load(Ordering::SeqCst)
|
pub fn interrupted() -> bool {
|
||||||
|
INTERRUPTED.load(Ordering::SeqCst)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_running(value: bool) {
|
/// Clears the interrupted flag
|
||||||
RUNNING.store(value, Ordering::SeqCst)
|
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) {
|
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() {
|
pub fn set_handler() {
|
||||||
let sig_action = signal::SigAction::new(
|
let sig_action = signal::SigAction::new(
|
||||||
signal::SigHandler::Handler(handle_sigint),
|
signal::SigHandler::Handler(handle_sigint),
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
pub fn running() -> bool {
|
//! A stub for Ctrl + C handling.
|
||||||
|
|
||||||
|
pub fn interrupted() -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_running(_value: bool) {}
|
pub fn unset_interrupted() {}
|
||||||
|
|
||||||
pub fn set_handler() {}
|
pub fn set_handler() {}
|
||||||
|
|||||||
10
src/main.rs
10
src/main.rs
@@ -31,13 +31,13 @@ where
|
|||||||
return Ok(Some((key, success)));
|
return Ok(Some((key, success)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let running = ctrlc::running();
|
let interrupted = ctrlc::interrupted();
|
||||||
if !running {
|
if interrupted {
|
||||||
ctrlc::set_running(true);
|
ctrlc::unset_interrupted();
|
||||||
}
|
}
|
||||||
|
|
||||||
let should_ask = !running || !no_retry;
|
let should_ask = interrupted || !no_retry;
|
||||||
let should_retry = should_ask && should_retry(running).context(ErrorKind::Retry)?;
|
let should_retry = should_ask && should_retry(interrupted).context(ErrorKind::Retry)?;
|
||||||
|
|
||||||
if !should_retry {
|
if !should_retry {
|
||||||
return Ok(Some((key, success)));
|
return Ok(Some((key, success)));
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ impl Terminal {
|
|||||||
.ok();
|
.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() {
|
if self.width.is_none() {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ impl Terminal {
|
|||||||
"\n{}",
|
"\n{}",
|
||||||
style(format!(
|
style(format!(
|
||||||
"Retry? [y/N] {}",
|
"Retry? [y/N] {}",
|
||||||
if !running {
|
if interrupted {
|
||||||
"(Press Ctrl+C again to stop Topgrade) "
|
"(Press Ctrl+C again to stop Topgrade) "
|
||||||
} else {
|
} else {
|
||||||
""
|
""
|
||||||
@@ -111,8 +111,8 @@ impl Default for Terminal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn should_retry(running: bool) -> Result<bool, io::Error> {
|
pub fn should_retry(interrupted: bool) -> Result<bool, io::Error> {
|
||||||
TERMINAL.lock().unwrap().should_retry(running)
|
TERMINAL.lock().unwrap().should_retry(interrupted)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn print_separator<P: AsRef<str>>(message: P) {
|
pub fn print_separator<P: AsRef<str>>(message: P) {
|
||||||
|
|||||||
Reference in New Issue
Block a user