From a404df9c97c95b2f96a95c6e4251ed676c09256a Mon Sep 17 00:00:00 2001 From: Roey Darwish Dror Date: Mon, 31 Dec 2018 14:07:55 +0200 Subject: [PATCH] Ctrl+C handling documentation --- src/ctrlc/mod.rs | 2 ++ src/ctrlc/unix.rs | 20 ++++++++++++++------ src/ctrlc/windows.rs | 6 ++++-- src/main.rs | 10 +++++----- src/terminal.rs | 8 ++++---- 5 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/ctrlc/mod.rs b/src/ctrlc/mod.rs index 25cf5bb3..4284cd92 100644 --- a/src/ctrlc/mod.rs +++ b/src/ctrlc/mod.rs @@ -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)] diff --git a/src/ctrlc/unix.rs b/src/ctrlc/unix.rs index 46c7c10e..d63eca81 100644 --- a/src/ctrlc/unix.rs +++ b/src/ctrlc/unix.rs @@ -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), diff --git a/src/ctrlc/windows.rs b/src/ctrlc/windows.rs index 83f9d380..56d413bb 100644 --- a/src/ctrlc/windows.rs +++ b/src/ctrlc/windows.rs @@ -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() {} diff --git a/src/main.rs b/src/main.rs index 6fa004fe..01f0a263 100644 --- a/src/main.rs +++ b/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))); diff --git a/src/terminal.rs b/src/terminal.rs index 4e920de1..610b63a2 100644 --- a/src/terminal.rs +++ b/src/terminal.rs @@ -70,7 +70,7 @@ impl Terminal { .ok(); } - fn should_retry(&mut self, running: bool) -> Result { + fn should_retry(&mut self, interrupted: bool) -> Result { 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 { - TERMINAL.lock().unwrap().should_retry(running) +pub fn should_retry(interrupted: bool) -> Result { + TERMINAL.lock().unwrap().should_retry(interrupted) } pub fn print_separator>(message: P) {