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 { | 
