From bb268d1500eabc2bf8efa193de4fc4923a06b66a Mon Sep 17 00:00:00 2001 From: Michael Debertol Date: Fri, 28 May 2021 22:39:33 +0200 Subject: [PATCH] sort: crash when failing to open an input file (#2265) * sort: crash when failing to open an input file Instead of ignoring files we fail to open, crash. The error message does not exactly match gnu, but that would require more effort. * use split_whitespace instead of a manual implementation * fix expected error on windows * sort: update expected error message --- src/uu/sort/src/check.rs | 2 +- src/uu/sort/src/merge.rs | 2 +- src/uu/sort/src/sort.rs | 13 ++++++------- tests/by-util/test_sort.rs | 18 ++++++++++++++++-- 4 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/uu/sort/src/check.rs b/src/uu/sort/src/check.rs index 01b5a25b5..d3b9d6669 100644 --- a/src/uu/sort/src/check.rs +++ b/src/uu/sort/src/check.rs @@ -26,7 +26,7 @@ use std::{ /// /// The code we should exit with. pub fn check(path: &str, settings: &GlobalSettings) -> i32 { - let file = open(path).expect("failed to open input file"); + let file = open(path); let (recycled_sender, recycled_receiver) = sync_channel(2); let (loaded_sender, loaded_receiver) = sync_channel(2); thread::spawn({ diff --git a/src/uu/sort/src/merge.rs b/src/uu/sort/src/merge.rs index 48d48ad40..696353829 100644 --- a/src/uu/sort/src/merge.rs +++ b/src/uu/sort/src/merge.rs @@ -29,7 +29,7 @@ pub fn merge<'a>(files: &[impl AsRef], settings: &'a GlobalSettings) -> F let (request_sender, request_receiver) = channel(); let mut reader_files = Vec::with_capacity(files.len()); let mut loaded_receivers = Vec::with_capacity(files.len()); - for (file_number, file) in files.iter().filter_map(open).enumerate() { + for (file_number, file) in files.iter().map(open).enumerate() { let (sender, receiver) = sync_channel(2); loaded_receivers.push(receiver); reader_files.push(ReaderFile { diff --git a/src/uu/sort/src/sort.rs b/src/uu/sort/src/sort.rs index 77be78390..0efce00e6 100644 --- a/src/uu/sort/src/sort.rs +++ b/src/uu/sort/src/sort.rs @@ -955,7 +955,7 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let mut files = Vec::new(); for path in &files0_from { - let reader = open(path.as_str()).expect("Could not read from file specified."); + let reader = open(path.as_str()); let buf_reader = BufReader::new(reader); for line in buf_reader.split(b'\0').flatten() { files.push( @@ -1116,7 +1116,7 @@ fn exec(files: &[String], settings: &GlobalSettings) -> i32 { } return check::check(files.first().unwrap(), settings); } else { - let mut lines = files.iter().filter_map(open); + let mut lines = files.iter().map(open); ext_sort(&mut lines, &settings); } @@ -1413,18 +1413,17 @@ fn print_sorted<'a, T: Iterator>>(iter: T, settings: &Global } // from cat.rs -fn open(path: impl AsRef) -> Option> { +fn open(path: impl AsRef) -> Box { let path = path.as_ref(); if path == "-" { let stdin = stdin(); - return Some(Box::new(stdin) as Box); + return Box::new(stdin) as Box; } match File::open(Path::new(path)) { - Ok(f) => Some(Box::new(f) as Box), + Ok(f) => Box::new(f) as Box, Err(e) => { - show_error!("{0:?}: {1}", path, e.to_string()); - None + crash!(2, "cannot read: {0:?}: {1}", path, e); } } } diff --git a/tests/by-util/test_sort.rs b/tests/by-util/test_sort.rs index 624c002d0..3c0af259f 100644 --- a/tests/by-util/test_sort.rs +++ b/tests/by-util/test_sort.rs @@ -4,14 +4,14 @@ fn test_helper(file_name: &str, possible_args: &[&str]) { for args in possible_args { new_ucmd!() .arg(format!("{}.txt", file_name)) - .args(&args.split(' ').collect::>()) + .args(&args.split_whitespace().collect::>()) .succeeds() .stdout_is_fixture(format!("{}.expected", file_name)); new_ucmd!() .arg(format!("{}.txt", file_name)) .arg("--debug") - .args(&args.split(' ').collect::>()) + .args(&args.split_whitespace().collect::>()) .succeeds() .stdout_is_fixture(format!("{}.expected.debug", file_name)); } @@ -723,3 +723,17 @@ fn test_trailing_separator() { .succeeds() .stdout_is("aax\naaa\n"); } + +#[test] +fn test_nonexistent_file() { + new_ucmd!() + .arg("nonexistent.txt") + .fails() + .status_code(2) + .stderr_only( + #[cfg(not(windows))] + "sort: cannot read: \"nonexistent.txt\": No such file or directory (os error 2)", + #[cfg(windows)] + "sort: cannot read: \"nonexistent.txt\": The system cannot find the file specified. (os error 2)", + ); +}