diff --git a/src/uu/fold/src/fold.rs b/src/uu/fold/src/fold.rs index ecd08264f0c..6d10b5c5a2d 100644 --- a/src/uu/fold/src/fold.rs +++ b/src/uu/fold/src/fold.rs @@ -13,6 +13,7 @@ use unicode_width::UnicodeWidthChar; use uucore::display::Quotable; use uucore::error::{FromIo, UResult, USimpleError}; use uucore::format_usage; +use uucore::show; use uucore::translate; const TAB_WIDTH: usize = 8; @@ -155,7 +156,14 @@ fn fold( stdin_buf = stdin(); &mut stdin_buf as &mut dyn Read } else { - file_buf = File::open(Path::new(filename)).map_err_context(|| filename.to_string())?; + // Like GNU, report the error but keep processing the remaining files. + match File::open(Path::new(filename)) { + Ok(f) => file_buf = f, + Err(e) => { + show!(e.map_err_context(|| filename.to_string())); + continue; + } + } &mut file_buf as &mut dyn Read }); diff --git a/tests/by-util/test_fold.rs b/tests/by-util/test_fold.rs index 23ac6c989a7..1981aaa9890 100644 --- a/tests/by-util/test_fold.rs +++ b/tests/by-util/test_fold.rs @@ -930,6 +930,21 @@ fn test_bytewise_fold_at_read_buffer_boundary() { .stdout_is_bytes(expected); } +#[test] +fn test_continue_after_missing_file() { + // A nonexistent operand must not abort the run: the surrounding files are + // still folded, the error is reported on stderr, and the exit status is 1. + let ts = TestScenario::new(util_name!()); + ts.fixtures.write("first.txt", "hello\n"); + ts.fixtures.write("third.txt", "world\n"); + + ts.ucmd() + .args(&["first.txt", "absent.txt", "third.txt"]) + .fails_with_code(1) + .stdout_is("hello\nworld\n") + .stderr_is("fold: absent.txt: No such file or directory\n"); +} + #[test] fn test_obsolete_syntax() { new_ucmd!()