Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/windirstat/walkdir.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Gallant <jamslam@gmail.com>2018-08-22 04:41:48 +0300
committerAndrew Gallant <jamslam@gmail.com>2018-08-22 04:41:48 +0300
commit6f72fce4315cb13f2ceb6903910a52852a12ba0b (patch)
treef10eae446705a4ac8c5e9eaa0ca0a653d8ad3112
parent7033d12ded2132000a3b6d4f5d49fe36eda9dc1b (diff)
path_is_symlink: fix false positive
This commit fixes a bug where the first path always reported itself as as symlink via `path_is_symlink`. Partially fixes https://github.com/BurntSushi/ripgrep/issues/984
-rw-r--r--src/lib.rs22
-rw-r--r--src/tests.rs15
2 files changed, 28 insertions, 9 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 0180818..58fc2e5 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -623,7 +623,7 @@ pub struct DirEntry {
/// The file type. Necessary for recursive iteration, so store it.
ty: FileType,
/// Is set when this entry was created from a symbolic link and the user
- /// excepts the iterator to follow symbolic links.
+ /// expects the iterator to follow symbolic links.
follow_link: bool,
/// The depth at which this entry was generated relative to the root.
depth: usize,
@@ -650,7 +650,7 @@ impl Iterator for IntoIter {
/// an error value. The error will be wrapped in an Option::Some.
fn next(&mut self) -> Option<Result<DirEntry>> {
if let Some(start) = self.start.take() {
- let dent = itry!(DirEntry::from_link(0, start));
+ let dent = itry!(DirEntry::from_path(0, start, false));
if let Some(result) = self.handle_entry(dent) {
return Some(result);
}
@@ -885,7 +885,11 @@ impl IntoIter {
}
fn follow(&self, mut dent: DirEntry) -> Result<DirEntry> {
- dent = DirEntry::from_link(self.depth, dent.path().to_path_buf())?;
+ dent = DirEntry::from_path(
+ self.depth,
+ dent.path().to_path_buf(),
+ true,
+ )?;
// The only way a symlink can cause a loop is if it points
// to a directory. Otherwise, it always points to a leaf
// and we can omit any loop checks.
@@ -1119,21 +1123,21 @@ impl DirEntry {
}
#[cfg(windows)]
- fn from_link(depth: usize, pb: PathBuf) -> Result<DirEntry> {
+ fn from_path(depth: usize, pb: PathBuf, link: bool) -> Result<DirEntry> {
let md = fs::metadata(&pb).map_err(|err| {
Error::from_path(depth, pb.clone(), err)
})?;
Ok(DirEntry {
path: pb,
ty: md.file_type(),
- follow_link: true,
+ follow_link: link,
depth: depth,
metadata: md,
})
}
#[cfg(unix)]
- fn from_link(depth: usize, pb: PathBuf) -> Result<DirEntry> {
+ fn from_path(depth: usize, pb: PathBuf, link: bool) -> Result<DirEntry> {
use std::os::unix::fs::MetadataExt;
let md = fs::metadata(&pb).map_err(|err| {
@@ -1142,21 +1146,21 @@ impl DirEntry {
Ok(DirEntry {
path: pb,
ty: md.file_type(),
- follow_link: true,
+ follow_link: link,
depth: depth,
ino: md.ino(),
})
}
#[cfg(not(any(unix, windows)))]
- fn from_link(depth: usize, pb: PathBuf) -> Result<DirEntry> {
+ fn from_path(depth: usize, pb: PathBuf, link: bool) -> Result<DirEntry> {
let md = fs::metadata(&pb).map_err(|err| {
Error::from_path(depth, pb.clone(), err)
})?;
Ok(DirEntry {
path: pb,
ty: md.file_type(),
- follow_link: true,
+ follow_link: link,
depth: depth,
})
}
diff --git a/src/tests.rs b/src/tests.rs
index be2f89b..8847323 100644
--- a/src/tests.rs
+++ b/src/tests.rs
@@ -516,6 +516,21 @@ fn walk_dir_sym_root() {
assert_eq!(got, vec!["foo/alink/", "foo/alink/a", "foo/alink/b"]);
}
+// See: https://github.com/BurntSushi/ripgrep/issues/984
+#[test]
+#[cfg(unix)]
+fn first_path_not_symlink() {
+ let exp = td("foo", vec![]);
+ let (tmp, _got) = dir_setup(&exp);
+
+ let dents = WalkDir::new(tmp.path().join("foo"))
+ .into_iter()
+ .collect::<Result<Vec<_>, _>>()
+ .unwrap();
+ assert_eq!(1, dents.len());
+ assert!(!dents[0].path_is_symlink());
+}
+
#[test]
#[cfg(unix)]
fn walk_dir_sym_detect_no_follow_no_loop() {