Skip to content

Commit

Permalink
walk: catch ignore NotFound error in the case of a broken symlink
Browse files Browse the repository at this point in the history
  • Loading branch information
tommilligan authored and sharkdp committed Feb 28, 2020
1 parent 3ca0210 commit 193e3c2
Showing 1 changed file with 39 additions and 3 deletions.
42 changes: 39 additions & 3 deletions src/walk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -231,7 +267,7 @@ fn spawn_receiver(
}
}
}
WorkerResult::Error(err) => {
Err(err) => {
if show_filesystem_errors {
print_error!("{}", err);
}
Expand Down

0 comments on commit 193e3c2

Please sign in to comment.