mirror of
https://github.com/sharkdp/fd.git
synced 2024-11-18 01:40:34 +01:00
walk: catch ignore NotFound error in the case of a broken symlink
This commit is contained in:
parent
06434f229b
commit
9d73402ef2
1 changed files with 39 additions and 3 deletions
42
src/walk.rs
42
src/walk.rs
|
@ -13,8 +13,10 @@ use crate::internal::{opts::FdOptions, osstr_to_bytes, MAX_BUFFER_LENGTH};
|
|||
use crate::output;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::convert::TryFrom;
|
||||
use std::error::Error;
|
||||
use std::ffi::OsStr;
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::path::PathBuf;
|
||||
use std::process;
|
||||
|
@ -44,6 +46,40 @@ pub enum WorkerResult {
|
|||
Error(ignore::Error),
|
||||
}
|
||||
|
||||
/// Converts a WorkerResult to a PathBuf. This is required as in some cases,
|
||||
/// the underlying `ignore` libary will return an error when we actually
|
||||
/// still want to show the path.
|
||||
///
|
||||
/// Currently, the cases supported are:
|
||||
/// - a broken symlink should still be found and the path returned
|
||||
impl TryFrom<WorkerResult> for PathBuf {
|
||||
type Error = ignore::Error;
|
||||
|
||||
fn try_from(worker_result: WorkerResult) -> Result<PathBuf, Self::Error> {
|
||||
match worker_result {
|
||||
WorkerResult::Entry(value) => return Ok(value),
|
||||
WorkerResult::Error(err) => {
|
||||
if let ignore::Error::WithPath {
|
||||
path,
|
||||
err: path_err,
|
||||
} = &err
|
||||
{
|
||||
if let ignore::Error::Io(io_err) = &**path_err {
|
||||
if io_err.kind() == io::ErrorKind::NotFound {
|
||||
if let Ok(metadata) = fs::symlink_metadata(&path) {
|
||||
if metadata.file_type().is_symlink() {
|
||||
return Ok(path.to_path_buf());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Recursively scan the given search path for files / pathnames matching the pattern.
|
||||
///
|
||||
/// If the `--exec` argument was supplied, this will create a thread pool for executing
|
||||
|
@ -201,8 +237,8 @@ fn spawn_receiver(
|
|||
let mut stdout = stdout.lock();
|
||||
|
||||
for worker_result in rx {
|
||||
match worker_result {
|
||||
WorkerResult::Entry(value) => {
|
||||
match PathBuf::try_from(worker_result) {
|
||||
Ok(value) => {
|
||||
match mode {
|
||||
ReceiverMode::Buffering => {
|
||||
buffer.push(value);
|
||||
|
@ -231,7 +267,7 @@ fn spawn_receiver(
|
|||
}
|
||||
}
|
||||
}
|
||||
WorkerResult::Error(err) => {
|
||||
Err(err) => {
|
||||
if show_filesystem_errors {
|
||||
print_error!("{}", err);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue