aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
authorDaniel Schadt <kingdread@gmx.de>2020-05-01 22:12:00 +0200
committerDaniel Schadt <kingdread@gmx.de>2020-05-01 22:12:00 +0200
commit0d1898ad881e05abf93c73fc8a13e4e5e5596335 (patch)
tree8cdcbb2c7f9dba7599020b1f5780349236706705 /src/main.rs
parent4e02a34827b0ae3ef5eb957ab142f5a4c0ece301 (diff)
downloadraidgrep-0d1898ad881e05abf93c73fc8a13e4e5e5596335.tar.gz
raidgrep-0d1898ad881e05abf93c73fc8a13e4e5e5596335.tar.bz2
raidgrep-0d1898ad881e05abf93c73fc8a13e4e5e5596335.zip
only cancel current search on Ctrl-C
This is not yet perfect, as it seems to still execute all queued threads just to immediately exit them, so maybe we should try and see if we can "clear" the rayon queue. But it's a good start, and the ctrlc crate seems to work well for this job.
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs13
1 files changed, 13 insertions, 0 deletions
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 {