diff options
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/main.rs | 13 |
2 files changed, 14 insertions, 0 deletions
@@ -34,6 +34,7 @@ log = { version = "0.4", features = ["std"] } thiserror = "1.0" lalrpop-util = "0.18" rustyline = "6.1" +ctrlc = "3.1" [build-dependencies] lalrpop = { version = "0.18", features = ["lexer"] } diff --git a/src/main.rs b/src/main.rs index cb67968..61c332e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use std::fs::File; use std::io::{BufReader, Read, Seek}; use std::path::PathBuf; use std::str::FromStr; +use std::sync::atomic::{AtomicBool, Ordering}; use anyhow::{anyhow, Error, Result}; use chrono::{DateTime, TimeZone, Utc}; @@ -220,6 +221,10 @@ impl fmt::Display for InputError { impl std::error::Error for InputError {} +/// A flag that indicates whether the current search should be interrupted because the user pressed +/// Crtl-C. +static INTERRUPTED: AtomicBool = AtomicBool::new(false); + fn main() { let result = run(); if let Err(err) = result { @@ -290,11 +295,15 @@ fn single(opt: &Opt) -> Result<()> { } fn repl(opt: &Opt) -> Result<()> { + ctrlc::set_handler(|| INTERRUPTED.store(true, Ordering::Relaxed)) + .expect("Could not set interrupt hanlder"); + let mut rl = Editor::<()>::new(); loop { let line = rl.readline("Query> ")?; rl.add_history_entry(&line); let parsed = build_filter(&line); + INTERRUPTED.store(false, Ordering::Relaxed); match parsed { Ok(filter) => grep(&opt, &*filter)?, Err(err) => display_error(&err), @@ -333,6 +342,10 @@ fn grep(opt: &Opt, filter: &dyn LogFilter) -> Result<()> { for entry in walker { let entry = entry?; s.spawn(move |_| { + // Check first if we should even still continue + if INTERRUPTED.load(Ordering::Relaxed) { + return; + } if is_log_file(&entry) { let search = search_log(&entry, filter); match search { |