From 9f0b70d1491c5a8524dec407ce7e56d34149a823 Mon Sep 17 00:00:00 2001 From: Devel Date: Sat, 27 Jun 2026 04:24:58 +0300 Subject: [PATCH 1/5] cp: when -g is passed with non-existent source, show the correct error --- src/uu/cp/src/cp.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 164ecd31f00..862aa81e7a8 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -840,7 +840,17 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { // code should still be EXIT_ERR as does GNU cp } else { // Else we caught a fatal bubbled-up error, log it to stderr - show_error!("{error}"); + + if let CpError::IoErr(ref error) = error { + if error.kind() == io::ErrorKind::NotFound { + show_error!( + "{}", + translate!("cp-error-cannot-stat", "source" => format!("'{}'",sources[0].display())) + ); + } + } else { + show_error!("{error}"); + } } set_exit_code(EXIT_ERR); } @@ -848,6 +858,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { Ok(()) } + impl ClobberMode { fn from_matches(matches: &ArgMatches) -> Self { if matches.get_flag(options::FORCE) { From d83798939dedb57fe5d9c95f4b21cf52245b1804 Mon Sep 17 00:00:00 2001 From: Devel Date: Sat, 27 Jun 2026 04:26:14 +0300 Subject: [PATCH 2/5] test_cp: add test_progressbar_inexistent_source --- tests/by-util/test_cp.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 6dc5ed61a62..6c24370c6ee 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -8067,3 +8067,13 @@ fn test_cp_p_preserves_posix_acls() { "cp -p must preserve POSIX ACLs (GNU tests/cp/acl regression)", ); } + +#[test] +fn test_progressbar_inexistent_source() { + let (_, mut ucmd) = at_and_ucmd!(); + ucmd.arg("-g") + .arg("inexistent1") + .arg("inexistent2") + .fails_with_code(1) + .stderr_contains("cp: cannot stat 'inexistent1': No such file or directory"); +} From 5104b193a674316d3fbd7f391e854181aa542a91 Mon Sep 17 00:00:00 2001 From: Devel Date: Sat, 27 Jun 2026 04:30:22 +0300 Subject: [PATCH 3/5] fmt --- src/uu/cp/src/cp.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 862aa81e7a8..981001c080f 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -858,7 +858,6 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { Ok(()) } - impl ClobberMode { fn from_matches(matches: &ArgMatches) -> Self { if matches.get_flag(options::FORCE) { From 86fc15f3e5861d165cd0ba4f3a71f1006cc49f23 Mon Sep 17 00:00:00 2001 From: Devel Date: Sat, 27 Jun 2026 04:59:56 +0300 Subject: [PATCH 4/5] remove unnecessary reference --- src/uu/cp/src/cp.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 981001c080f..7acc9e48d49 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -841,7 +841,7 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { } else { // Else we caught a fatal bubbled-up error, log it to stderr - if let CpError::IoErr(ref error) = error { + if let CpError::IoErr(error) = error { if error.kind() == io::ErrorKind::NotFound { show_error!( "{}", From 96a2abc9352f8c5e999a7dea934b8dcaceb1d1c2 Mon Sep 17 00:00:00 2001 From: Devel Date: Sun, 28 Jun 2026 17:15:27 +0300 Subject: [PATCH 5/5] use match instead if/els --- src/uu/cp/src/cp.rs | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 7acc9e48d49..73da0af8ea4 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -835,20 +835,20 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let (sources, target) = parse_path_args(paths, &options)?; if let Err(error) = copy(&sources, &target, &options) { - if let CpError::NotAllFilesCopied = error { - // Error::NotAllFilesCopied is non-fatal, but the error - // code should still be EXIT_ERR as does GNU cp - } else { - // Else we caught a fatal bubbled-up error, log it to stderr - - if let CpError::IoErr(error) = error { - if error.kind() == io::ErrorKind::NotFound { - show_error!( - "{}", - translate!("cp-error-cannot-stat", "source" => format!("'{}'",sources[0].display())) - ); - } - } else { + match error { + CpError::NotAllFilesCopied => { + // non-fatal; exit code still EXIT_ERR + } + CpError::IoErr(io_err) if io_err.kind() == io::ErrorKind::NotFound => { + show_error!( + "{}", + translate!( + "cp-error-cannot-stat", + "source" => format!("'{}'", sources[0].display()) + ) + ); + } + _ => { show_error!("{error}"); } }