From 827aad57dcb3ddd30c84f927348ad064becb15e3 Mon Sep 17 00:00:00 2001 From: Cameron Cordes Date: Mon, 15 Feb 2021 20:06:45 -0500 Subject: [PATCH] Use our own struct instead of accumulating DirEntrys DirEntry keeps a handle to an open file, so keeping a reference to them while traversing a large directory, such as a home directory, can trigger a too many open files error. --- src/main.rs | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index a76f13e..71f009b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,7 +22,18 @@ mod rack { struct Traversal { dirs: Vec, - entries: Vec, + entries: Vec, + } + + struct SearchableFile { + path: PathBuf, + } + + /// Use our own structure since DirEntry keeps hold of open files until they are dropped + impl From for SearchableFile { + fn from(entry: DirEntry) -> SearchableFile { + SearchableFile { path: entry.path() } + } } impl Rack { @@ -93,22 +104,25 @@ mod rack { continue; } - if let Ok(mut contents) = Rack::get_dir_entries(path) { - traversal.dirs.append(&mut contents); - } + match Rack::get_dir_entries(path) { + Ok(mut contents) => { + traversal.dirs.append(&mut contents); + } + Err(msg) => println!("Error reading dir: {}. {}", path, msg), + }; } else { if self.should_ignore(&gitignore, path, &entry) { continue; } - traversal.entries.push(entry); + traversal.entries.push(entry.into()); } } let mut results = traversal .entries .iter() - .filter_map(|e| self.check_file(&e.path()).ok()) + .filter_map(|e| self.check_file(&e.path).ok()) .filter(|mat| mat.matches.len() > 0) .collect::>(); self.matches.append(&mut results);