Fix directory-existence check on Windows

This fixes a bug on Windows where `fd` could not be used on ram disks
and encrypted folders.

closes #752
This commit is contained in:
David Peter 2021-08-08 13:24:56 +02:00 committed by David Peter
parent 6e44828cc8
commit 2d398dc4a7
4 changed files with 23 additions and 8 deletions

12
Cargo.lock generated
View file

@ -1,5 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "0.7.18"
@ -166,6 +168,7 @@ dependencies = [
"lazy_static",
"libc",
"lscolors",
"normpath",
"num_cpus",
"regex",
"regex-syntax",
@ -330,6 +333,15 @@ dependencies = [
"libc",
]
[[package]]
name = "normpath"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27e6e8f70e9fbbe3752d330d769e3424f24b9458ce266df93a3b456902fd696a"
dependencies = [
"winapi",
]
[[package]]
name = "num_cpus"
version = "1.13.0"

View file

@ -47,6 +47,7 @@ lscolors = "0.7"
globset = "0.4"
anyhow = "1.0"
dirs-next = "2.0"
normpath = "0.3"
[dependencies.clap]
version = "2.31.2"

View file

@ -7,6 +7,8 @@ use std::io;
use std::os::unix::fs::{FileTypeExt, PermissionsExt};
use std::path::{Path, PathBuf};
use normpath::PathExt;
use crate::walk;
pub fn path_absolute_form(path: &Path) -> io::Result<PathBuf> {
@ -33,10 +35,10 @@ pub fn absolute_path(path: &Path) -> io::Result<PathBuf> {
Ok(path_buf)
}
// Path::is_dir() is not guaranteed to be intuitively correct for "." and ".."
// See: https://github.com/rust-lang/rust/issues/45302
pub fn is_dir(path: &Path) -> bool {
path.is_dir() && (path.file_name().is_some() || path.canonicalize().is_ok())
pub fn is_existing_directory(path: &Path) -> bool {
// Note: we do not use `.exists()` here, as `.` always exists, even if
// the CWD has been deleted.
path.is_dir() && (path.file_name().is_some() || path.normalize().is_ok())
}
#[cfg(any(unix, target_os = "redox"))]

View file

@ -55,7 +55,7 @@ fn run() -> Result<ExitCode> {
// Set the current working directory of the process
if let Some(base_directory) = matches.value_of_os("base-directory") {
let base_directory = Path::new(base_directory);
if !filesystem::is_dir(base_directory) {
if !filesystem::is_existing_directory(base_directory) {
return Err(anyhow!(
"The '--base-directory' path '{}' is not a directory.",
base_directory.to_string_lossy()
@ -70,7 +70,7 @@ fn run() -> Result<ExitCode> {
}
let current_directory = Path::new(".");
if !filesystem::is_dir(current_directory) {
if !filesystem::is_existing_directory(current_directory) {
return Err(anyhow!(
"Could not retrieve current directory (has it been deleted?)."
));
@ -95,7 +95,7 @@ fn run() -> Result<ExitCode> {
let mut directories = vec![];
for path in paths {
let path_buffer = PathBuf::from(path);
if filesystem::is_dir(&path_buffer) {
if filesystem::is_existing_directory(&path_buffer) {
directories.push(path_buffer);
} else {
print_error(format!(
@ -130,7 +130,7 @@ fn run() -> Result<ExitCode> {
// Detect if the user accidentally supplied a path instead of a search pattern
if !matches.is_present("full-path")
&& pattern.contains(std::path::MAIN_SEPARATOR)
&& filesystem::is_dir(Path::new(pattern))
&& Path::new(pattern).is_dir()
{
return Err(anyhow!(
"The search pattern '{pattern}' contains a path-separation character ('{sep}') \