mirror of
https://github.com/uutils/findutils.git
synced 2026-06-10 15:48:30 -07:00
samefile: Cache FileInformation for the target (#409)
And don't follow symlinks.
This commit is contained in:
@@ -540,16 +540,10 @@ fn build_matcher_tree(
|
||||
if i >= args.len() - 1 {
|
||||
return Err(From::from(format!("missing argument to {}", args[i])));
|
||||
}
|
||||
let path = Path::new(args[i + 1]).to_path_buf();
|
||||
// check if path is not found
|
||||
if !path.exists() {
|
||||
return Err(From::from(format!(
|
||||
"{}: No such file or directory",
|
||||
args[i + 1]
|
||||
)));
|
||||
}
|
||||
i += 1;
|
||||
Some(SameFileMatcher::new(path).into_box())
|
||||
let path = args[i];
|
||||
let matcher = SameFileMatcher::new(path).map_err(|e| format!("{path}: {e}"))?;
|
||||
Some(matcher.into_box())
|
||||
}
|
||||
"-user" => {
|
||||
if i >= args.len() - 1 {
|
||||
|
||||
@@ -3,23 +3,29 @@
|
||||
// For the full copyright and license information, please view the LICENSE
|
||||
// file that was distributed with this source code.
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use super::Matcher;
|
||||
use std::error::Error;
|
||||
use std::path::Path;
|
||||
use uucore::fs::FileInformation;
|
||||
|
||||
pub struct SameFileMatcher {
|
||||
path: PathBuf,
|
||||
info: FileInformation,
|
||||
}
|
||||
|
||||
impl SameFileMatcher {
|
||||
pub fn new(path: PathBuf) -> SameFileMatcher {
|
||||
SameFileMatcher { path }
|
||||
pub fn new(path: impl AsRef<Path>) -> Result<Self, Box<dyn Error>> {
|
||||
let info = FileInformation::from_path(path, false)?;
|
||||
Ok(Self { info })
|
||||
}
|
||||
}
|
||||
|
||||
impl Matcher for SameFileMatcher {
|
||||
fn matches(&self, file_info: &walkdir::DirEntry, _matcher_io: &mut super::MatcherIO) -> bool {
|
||||
uucore::fs::paths_refer_to_same_file(file_info.path(), &self.path, true)
|
||||
if let Ok(info) = FileInformation::from_path(file_info.path(), false) {
|
||||
info == self.info
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,11 +44,14 @@ mod tests {
|
||||
// But you can't delete a file that doesn't exist,
|
||||
// so ignore the error returned here.
|
||||
let _ = fs::remove_file("test_data/links/hard_link");
|
||||
|
||||
assert!(SameFileMatcher::new("test_data/links/hard_link").is_err());
|
||||
|
||||
fs::hard_link("test_data/links/abbbc", "test_data/links/hard_link").unwrap();
|
||||
|
||||
let file = get_dir_entry_for("test_data/links", "abbbc");
|
||||
let hard_link_file = get_dir_entry_for("test_data/links", "hard_link");
|
||||
let matcher = SameFileMatcher::new(file.into_path());
|
||||
let matcher = SameFileMatcher::new(file.into_path()).unwrap();
|
||||
|
||||
let deps = FakeDependencies::new();
|
||||
assert!(matcher.matches(&hard_link_file, &mut deps.new_matcher_io()));
|
||||
|
||||
@@ -878,6 +878,6 @@ fn find_samefile() {
|
||||
.args([".", "-samefile", "./test_data/links/not-exist-file"])
|
||||
.assert()
|
||||
.failure()
|
||||
.stdout(predicate::str::contains(""))
|
||||
.stderr(predicate::str::contains("No such file or directory"));
|
||||
.stdout(predicate::str::is_empty())
|
||||
.stderr(predicate::str::contains("not-exist-file"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user