From d8e2ce20ceb9dffae11a9cd1e12da2ba256a4fcc Mon Sep 17 00:00:00 2001 From: hanbings Date: Mon, 8 Apr 2024 21:24:25 +0800 Subject: [PATCH] find: Changed exit code when an error is encountered in `process_dir()`. (#352) * Add an error flag to process_dir(). * Added no permission file error test. * Restore files after no permission file test. * Adjust the timing of matcher_io creation in process_dir(). * Use uucore::error to set global return code. --- src/find/mod.rs | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/src/find/mod.rs b/src/find/mod.rs index b1ba446..002dd34 100644 --- a/src/find/mod.rs +++ b/src/find/mod.rs @@ -150,7 +150,10 @@ fn process_dir<'a>( let mut it = walkdir.into_iter(); while let Some(result) = it.next() { match result { - Err(err) => writeln!(&mut stderr(), "Error: {dir}: {err}").unwrap(), + Err(err) => { + uucore::error::set_exit_code(1); + writeln!(&mut stderr(), "Error: {dir}: {err}").unwrap() + } Ok(entry) => { let mut matcher_io = matchers::MatcherIO::new(deps); if matcher.matches(&entry, &mut matcher_io) { @@ -254,7 +257,7 @@ fn print_version() { /// the name of the executable. pub fn find_main<'a>(args: &[&str], deps: &'a dyn Dependencies<'a>) -> i32 { match do_find(&args[1..], deps) { - Ok(_) => 0, + Ok(_) => uucore::error::get_exit_code(), Err(e) => { writeln!(&mut stderr(), "Error: {e}").unwrap(); 1 @@ -986,4 +989,40 @@ mod tests { assert_eq!(rc, 1); } } + + #[test] + #[cfg(target_os = "linux")] + fn test_no_permission_file_error() { + use std::{path::Path, process::Command}; + + let path = Path::new("./test_data/no_permission"); + let _result = fs::create_dir(&path); + // Generate files without permissions. + // std::fs cannot change file permissions to 000 in normal user state, + // so use chmod via Command to change permissions. + let _output = Command::new("chmod") + .arg("-rwx") + .arg("./test_data/no_permission") + .output() + .expect("cannot set file permission"); + + let deps = FakeDependencies::new(); + let rc = find_main(&["find", "./test_data/no_permission"], &deps); + + assert_eq!(rc, 1); + + // Reset the exit code global variable in case we run another test after this one + // See https://github.com/uutils/coreutils/issues/5777 + uucore::error::set_exit_code(0); + + if path.exists() { + let _result = fs::create_dir(&path); + // Remove the unreadable and writable status of the file to avoid affecting other tests. + let _output = Command::new("chmod") + .arg("+rwx") + .arg("./test_data/no_permission") + .output() + .expect("cannot set file permission"); + } + } }