From 58f6afdeb4f4b3901a13d92a9945c7d10cc4b812 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Tue, 7 Jan 2025 23:53:52 +0100 Subject: [PATCH 1/4] env: handle the error properly instead of: env: unknown error: Os { code: 13, kind: PermissionDenied, message: "Permission denied" } --- src/uu/env/src/env.rs | 23 +++++++++++++---------- tests/by-util/test_env.rs | 9 +++++++++ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/uu/env/src/env.rs b/src/uu/env/src/env.rs index ea31c01079e..b000857a882 100644 --- a/src/uu/env/src/env.rs +++ b/src/uu/env/src/env.rs @@ -539,16 +539,19 @@ impl EnvAppData { } return Err(exit.code().unwrap().into()); } - Err(ref err) - if (err.kind() == io::ErrorKind::NotFound) - || (err.kind() == io::ErrorKind::InvalidInput) => - { - return Err(self.make_error_no_such_file_or_dir(prog.deref())); - } - Err(e) => { - uucore::show_error!("unknown error: {:?}", e); - return Err(126.into()); - } + Err(ref err) => match err.kind() { + io::ErrorKind::NotFound | io::ErrorKind::InvalidInput => { + return Err(self.make_error_no_such_file_or_dir(prog.deref())); + } + io::ErrorKind::PermissionDenied => { + uucore::show_error!("{}: Permission denied", prog.quote()); + return Err(126.into()); + } + _ => { + uucore::show_error!("unknown error: {:?}", err); + return Err(126.into()); + } + }, Ok(_) => (), } Ok(()) diff --git a/tests/by-util/test_env.rs b/tests/by-util/test_env.rs index 2b33f725dbe..79ca0d2f45c 100644 --- a/tests/by-util/test_env.rs +++ b/tests/by-util/test_env.rs @@ -80,6 +80,15 @@ fn test_env_version() { .stdout_contains(util_name!()); } +#[test] +fn test_env_permissions() { + new_ucmd!() + .arg(".") + .fails() + .code_is(126) + .stderr_is("env: '.': Permission denied\n"); +} + #[test] fn test_echo() { #[cfg(target_os = "windows")] From 79645d45ce1e041183a8200d64442a3722c52c41 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 8 Jan 2025 00:05:11 +0100 Subject: [PATCH 2/4] stdbuf: better handling of the error message when no perm Tested in tests/misc/stdbuf --- src/uu/stdbuf/src/stdbuf.rs | 19 ++++++++++++++++--- tests/by-util/test_stdbuf.rs | 10 ++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/uu/stdbuf/src/stdbuf.rs b/src/uu/stdbuf/src/stdbuf.rs index bc7b2394911..e566439f0f9 100644 --- a/src/uu/stdbuf/src/stdbuf.rs +++ b/src/uu/stdbuf/src/stdbuf.rs @@ -157,9 +157,22 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { set_command_env(&mut command, "_STDBUF_E", &options.stderr); command.args(command_params); - let mut process = command - .spawn() - .map_err_context(|| "failed to execute process".to_string())?; + let mut process = match command.spawn() { + Ok(process) => process, + Err(e) if e.kind() == std::io::ErrorKind::PermissionDenied => { + return Err(USimpleError::new( + 126, + "failed to execute process: Permission denied", + )); + } + Err(e) => { + return Err(USimpleError::new( + 1, + format!("failed to execute process: {}", e), + )); + } + }; + let status = process.wait().map_err_context(String::new)?; match status.code() { Some(i) => { diff --git a/tests/by-util/test_stdbuf.rs b/tests/by-util/test_stdbuf.rs index a86f893e084..c2d7f9121d9 100644 --- a/tests/by-util/test_stdbuf.rs +++ b/tests/by-util/test_stdbuf.rs @@ -10,6 +10,16 @@ fn invalid_input() { new_ucmd!().arg("-/").fails().code_is(125); } +#[test] +fn test_permission() { + new_ucmd!() + .arg("-o1") + .arg(".") + .fails() + .code_is(126) + .stderr_contains("Permission denied"); +} + #[cfg(all(not(target_os = "windows"), not(target_os = "openbsd")))] #[test] fn test_stdbuf_unbuffered_stdout() { From 04d4c9e1ef9824f02d46d72d3c278cf1813b2f54 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 8 Jan 2025 00:11:34 +0100 Subject: [PATCH 3/4] stdbuf: better handling when non existing files Should fix tests/misc/stdbuf --- src/uu/stdbuf/src/stdbuf.rs | 32 ++++++++++++++++++++------------ tests/by-util/test_stdbuf.rs | 10 ++++++++++ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/uu/stdbuf/src/stdbuf.rs b/src/uu/stdbuf/src/stdbuf.rs index e566439f0f9..8c20cc39a2f 100644 --- a/src/uu/stdbuf/src/stdbuf.rs +++ b/src/uu/stdbuf/src/stdbuf.rs @@ -159,18 +159,26 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let mut process = match command.spawn() { Ok(process) => process, - Err(e) if e.kind() == std::io::ErrorKind::PermissionDenied => { - return Err(USimpleError::new( - 126, - "failed to execute process: Permission denied", - )); - } - Err(e) => { - return Err(USimpleError::new( - 1, - format!("failed to execute process: {}", e), - )); - } + Err(e) => match e.kind() { + std::io::ErrorKind::PermissionDenied => { + return Err(USimpleError::new( + 126, + "failed to execute process: Permission denied", + )); + } + std::io::ErrorKind::NotFound => { + return Err(USimpleError::new( + 127, + "failed to execute process: No such file or directory", + )); + } + _ => { + return Err(USimpleError::new( + 1, + format!("failed to execute process: {}", e), + )); + } + }, }; let status = process.wait().map_err_context(String::new)?; diff --git a/tests/by-util/test_stdbuf.rs b/tests/by-util/test_stdbuf.rs index c2d7f9121d9..4bee30fab14 100644 --- a/tests/by-util/test_stdbuf.rs +++ b/tests/by-util/test_stdbuf.rs @@ -20,6 +20,16 @@ fn test_permission() { .stderr_contains("Permission denied"); } +#[test] +fn test_no_such() { + new_ucmd!() + .arg("-o1") + .arg("no_such") + .fails() + .code_is(127) + .stderr_contains("No such file or directory"); +} + #[cfg(all(not(target_os = "windows"), not(target_os = "openbsd")))] #[test] fn test_stdbuf_unbuffered_stdout() { From 20e043c5fce5b899c66e76f5893e82ff1a34eab1 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 8 Jan 2025 00:16:37 +0100 Subject: [PATCH 4/4] stdbuf: Improve the code --- src/uu/stdbuf/src/stdbuf.rs | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/uu/stdbuf/src/stdbuf.rs b/src/uu/stdbuf/src/stdbuf.rs index 8c20cc39a2f..4540c60d89f 100644 --- a/src/uu/stdbuf/src/stdbuf.rs +++ b/src/uu/stdbuf/src/stdbuf.rs @@ -157,28 +157,22 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { set_command_env(&mut command, "_STDBUF_E", &options.stderr); command.args(command_params); + const EXEC_ERROR: &str = "failed to execute process:"; let mut process = match command.spawn() { - Ok(process) => process, - Err(e) => match e.kind() { - std::io::ErrorKind::PermissionDenied => { - return Err(USimpleError::new( + Ok(p) => p, + Err(e) => { + return match e.kind() { + std::io::ErrorKind::PermissionDenied => Err(USimpleError::new( 126, - "failed to execute process: Permission denied", - )); - } - std::io::ErrorKind::NotFound => { - return Err(USimpleError::new( + format!("{EXEC_ERROR} Permission denied"), + )), + std::io::ErrorKind::NotFound => Err(USimpleError::new( 127, - "failed to execute process: No such file or directory", - )); - } - _ => { - return Err(USimpleError::new( - 1, - format!("failed to execute process: {}", e), - )); + format!("{EXEC_ERROR} No such file or directory"), + )), + _ => Err(USimpleError::new(1, format!("{EXEC_ERROR} {}", e))), } - }, + } }; let status = process.wait().map_err_context(String::new)?;