From 1318a10eed75dcb7a3a86a9a9f2ab0d3e093f586 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9C=BF=20Fleur=20de=20Blue?= <135421389+Xylphy@users.noreply.github.com> Date: Tue, 4 Aug 2026 22:48:40 +0800 Subject: [PATCH 1/2] fix: proper error message --- src/find/mod.rs | 26 ++++++++++++++++++++++---- tests/test_find.rs | 16 ++++++++++++++++ 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/find/mod.rs b/src/find/mod.rs index ff047c82..eafae005 100644 --- a/src/find/mod.rs +++ b/src/find/mod.rs @@ -15,6 +15,7 @@ use std::io::{self, stderr, stdout, BufRead, BufReader, Write}; use std::path::PathBuf; use std::rc::Rc; use std::time::SystemTime; +use uucore::error; use walkdir::WalkDir; pub struct Config { @@ -160,6 +161,8 @@ struct ParsedInfo { /// struct Files0Paths { reader: Box, + /// Kept so that read errors can be reported GNU-style with the offending file name. + name: String, } impl Files0Paths { @@ -168,11 +171,19 @@ impl Files0Paths { let reader: Box = if name == "-" { Box::new(BufReader::new(io::stdin())) } else { - let file = std::fs::File::open(name) - .map_err(|e| format!("cannot open '{}' for reading: {}", name, e))?; + let file = std::fs::File::open(name).map_err(|e| { + format!( + "cannot open ‘{}’ for reading: {}", + name, + error::strip_errno(&e) + ) + })?; Box::new(BufReader::new(file)) }; - Ok(Self { reader }) + Ok(Self { + reader, + name: name.to_string(), + }) } } @@ -183,7 +194,14 @@ impl Iterator for Files0Paths { loop { let mut buffer = Vec::new(); match self.reader.read_until(0, &mut buffer) { - Err(e) => return Some(Err(e.into())), + Err(e) => { + return Some(Err(format!( + "‘{}’: read error: {}", + self.name, + error::strip_errno(&e) + ) + .into())); + } Ok(0) => return None, Ok(_) => {} } diff --git a/tests/test_find.rs b/tests/test_find.rs index 0fab96dd..49b54ce9 100644 --- a/tests/test_find.rs +++ b/tests/test_find.rs @@ -1631,3 +1631,19 @@ fn find_exits_cleanly_on_broken_pipe() { "find panicked instead of exiting cleanly on a broken pipe:\n{stderr}" ); } + +#[test] +#[cfg(target_os = "linux")] +fn files0_from_special_file_read_error() { + for path in &["/dev/vhost-net", "/dev/vhost-vsock"] { + if !Path::new(path).exists() { + continue; + } + ucmd() + .arg("-files0-from") + .arg(path) + .fails() + .stderr_contains("read error") + .no_stdout(); + } +} From b8239f7a44b6cd40642616cb3457b43a0c766aff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9C=BF=20Fleur=20de=20Blue?= <135421389+Xylphy@users.noreply.github.com> Date: Tue, 4 Aug 2026 23:33:47 +0800 Subject: [PATCH 2/2] test(find): accept open-permission errors in files0 special-file test --- tests/test_find.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/tests/test_find.rs b/tests/test_find.rs index 49b54ce9..7285f850 100644 --- a/tests/test_find.rs +++ b/tests/test_find.rs @@ -1639,11 +1639,15 @@ fn files0_from_special_file_read_error() { if !Path::new(path).exists() { continue; } - ucmd() - .arg("-files0-from") - .arg(path) - .fails() - .stderr_contains("read error") - .no_stdout(); + + let file_list_failure = ucmd().arg("-files0-from").arg(path).fails(); + + let error_output = file_list_failure.no_stdout().stderr_str(); + assert!( + error_output.contains("read error") + || (error_output.contains("cannot open") + && error_output.contains("Permission denied")), + "unexpected stderr for {path}: {error_output}" + ); } }