summaryrefslogtreecommitdiffstats
path: root/src/args.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/args.rs')
-rw-r--r--src/args.rs36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/args.rs b/src/args.rs
index 6aec396b..29a7fa81 100644
--- a/src/args.rs
+++ b/src/args.rs
@@ -15,6 +15,7 @@ use grep::{Grep, GrepBuilder};
use log;
use num_cpus;
use regex;
+use same_file;
use termcolor;
use app;
@@ -65,6 +66,7 @@ pub struct Args {
quiet_matched: QuietMatched,
replace: Option<Vec<u8>>,
sort_files: bool,
+ stdout_handle: Option<same_file::Handle>,
text: bool,
threads: usize,
type_list: bool,
@@ -182,6 +184,17 @@ impl Args {
termcolor::Stdout::new(self.color_choice)
}
+ /// Returns a handle to stdout for filtering search.
+ ///
+ /// A handle is returned if and only if ripgrep's stdout is being
+ /// redirected to a file. The handle returned corresponds to that file.
+ ///
+ /// This can be used to ensure that we do not attempt to search a file
+ /// that ripgrep is writing to.
+ pub fn stdout_handle(&self) -> Option<&same_file::Handle> {
+ self.stdout_handle.as_ref()
+ }
+
/// Create a new buffer writer for multi-threaded searching with color
/// support.
pub fn buffer_writer(&self) -> termcolor::BufferWriter {
@@ -338,6 +351,7 @@ impl<'a> ArgMatches<'a> {
quiet_matched: QuietMatched::new(quiet),
replace: self.replace(),
sort_files: self.is_present("sort-files"),
+ stdout_handle: self.stdout_handle(),
text: self.text(),
threads: try!(self.threads()),
type_list: self.is_present("type-list"),
@@ -518,6 +532,28 @@ impl<'a> ArgMatches<'a> {
}
}
+ /// Returns a handle to stdout for filtering search.
+ ///
+ /// A handle is returned if and only if ripgrep's stdout is being
+ /// redirected to a file. The handle returned corresponds to that file.
+ ///
+ /// This can be used to ensure that we do not attempt to search a file
+ /// that ripgrep is writing to.
+ fn stdout_handle(&self) -> Option<same_file::Handle> {
+ let h = match same_file::Handle::stdout() {
+ Err(_) => return None,
+ Ok(h) => h,
+ };
+ let md = match h.as_file().metadata() {
+ Err(_) => return None,
+ Ok(md) => md,
+ };
+ if !md.is_file() {
+ return None;
+ }
+ Some(h)
+ }
+
/// Returns true if and only if memory map searching should be tried.
///
/// `paths` should be a slice of all top-level file paths that ripgrep