diff --git a/src/uu/ls/src/ls.rs b/src/uu/ls/src/ls.rs index d9e93b6cb..80cb25389 100644 --- a/src/uu/ls/src/ls.rs +++ b/src/uu/ls/src/ls.rs @@ -153,7 +153,7 @@ const DEFAULT_BLOCK_SIZE: u64 = 1024; enum LsError { InvalidLineWidth(String), IOError(std::io::Error), - IOErrorContext(std::io::Error, PathBuf), + IOErrorContext(std::io::Error, PathBuf, bool), BlockSizeParseError(String), AlreadyListedError(PathBuf), } @@ -163,7 +163,8 @@ impl UError for LsError { match self { Self::InvalidLineWidth(_) => 2, Self::IOError(_) => 1, - Self::IOErrorContext(_, _) => 1, + Self::IOErrorContext(_, _, false) => 1, + Self::IOErrorContext(_, _, true) => 2, Self::BlockSizeParseError(_) => 1, Self::AlreadyListedError(_) => 2, } @@ -180,7 +181,7 @@ impl Display for LsError { } Self::InvalidLineWidth(s) => write!(f, "invalid line width: {}", s.quote()), Self::IOError(e) => write!(f, "general io error: {}", e), - Self::IOErrorContext(e, p) => { + Self::IOErrorContext(e, p, _) => { let error_kind = e.kind(); let errno = e.raw_os_error().unwrap_or(1i32); @@ -1566,6 +1567,7 @@ struct PathData { p_buf: PathBuf, must_dereference: bool, security_context: String, + command_line: bool, } impl PathData { @@ -1649,6 +1651,7 @@ impl PathData { p_buf, must_dereference, security_context, + command_line, } } @@ -1677,7 +1680,11 @@ impl PathData { return dir_entry.metadata().ok(); } } - show!(LsError::IOErrorContext(err, self.p_buf.clone(),)); + show!(LsError::IOErrorContext( + err, + self.p_buf.clone(), + self.command_line + )); None } Ok(md) => Some(md), @@ -1739,7 +1746,11 @@ pub fn list(locs: Vec<&Path>, config: &Config) -> UResult<()> { Err(err) => { // flush stdout buffer before the error to preserve formatting and order out.flush()?; - show!(LsError::IOErrorContext(err, path_data.p_buf.clone())); + show!(LsError::IOErrorContext( + err, + path_data.p_buf.clone(), + path_data.command_line + )); continue; } Ok(rd) => rd, @@ -1916,7 +1927,11 @@ fn enter_directory( match fs::read_dir(&e.p_buf) { Err(err) => { out.flush()?; - show!(LsError::IOErrorContext(err, e.p_buf.clone())); + show!(LsError::IOErrorContext( + err, + e.p_buf.clone(), + e.command_line + )); continue; } Ok(rd) => { diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index c1df743ea..2b11961b8 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -385,6 +385,7 @@ fn test_ls_io_errors() { .arg("-1") .arg("some-dir1") .fails() + .code_is(2) .stderr_contains("cannot open directory") .stderr_contains("Permission denied"); @@ -393,6 +394,7 @@ fn test_ls_io_errors() { .arg("-Li") .arg("some-dir2") .fails() + .code_is(1) .stderr_contains("cannot access") .stderr_contains("No such file or directory") .stdout_contains(if cfg!(windows) { "dangle" } else { "? dangle" }); @@ -408,6 +410,7 @@ fn test_ls_io_errors() { .arg("-laR") .arg("some-dir3") .fails() + .code_is(1) .stderr_contains("some-dir4") .stderr_contains("cannot open directory") .stderr_contains("Permission denied") @@ -2987,8 +2990,18 @@ fn test_ls_dangling_symlinks() { at.mkdir("temp_dir"); at.symlink_file("does_not_exist", "temp_dir/dangle"); - scene.ucmd().arg("-L").arg("temp_dir/dangle").fails(); - scene.ucmd().arg("-H").arg("temp_dir/dangle").fails(); + scene + .ucmd() + .arg("-L") + .arg("temp_dir/dangle") + .fails() + .code_is(2); + scene + .ucmd() + .arg("-H") + .arg("temp_dir/dangle") + .fails() + .code_is(2); scene .ucmd() @@ -3001,6 +3014,7 @@ fn test_ls_dangling_symlinks() { .arg("-Li") .arg("temp_dir") .fails() + .code_is(1) .stderr_contains("cannot access") .stderr_contains("No such file or directory") .stdout_contains(if cfg!(windows) { "dangle" } else { "? dangle" }); @@ -3010,6 +3024,7 @@ fn test_ls_dangling_symlinks() { .arg("-Ll") .arg("temp_dir") .fails() + .code_is(1) .stdout_contains("l?????????"); #[cfg(unix)] @@ -3018,6 +3033,7 @@ fn test_ls_dangling_symlinks() { at.touch("temp_dir/real_file"); let real_file_res = scene.ucmd().arg("-Li1").arg("temp_dir").fails(); + real_file_res.code_is(1); let real_file_stdout_len = String::from_utf8(real_file_res.stdout().to_owned()) .ok() .unwrap() @@ -3029,6 +3045,7 @@ fn test_ls_dangling_symlinks() { .len(); let dangle_file_res = scene.ucmd().arg("-Li1").arg("temp_dir").fails(); + dangle_file_res.code_is(1); let dangle_stdout_len = String::from_utf8(dangle_file_res.stdout().to_owned()) .ok() .unwrap() @@ -3199,6 +3216,7 @@ fn test_ls_dereference_looped_symlinks_recursive() { ucmd.args(&["-RL", "loop"]) .fails() + .code_is(2) .stderr_contains("not listing already-listed directory"); }