From 0d5daacf9949d1f35604d4f16fbf0bf3dd16bd9a Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 25 Mar 2023 10:47:57 +0100 Subject: [PATCH 1/4] mv -i: adjust the behavior to match the GNU change Matches the change upstream 7a69df88999bedd8e9fccf9f3dfa9ac6907fab66 --- src/uu/mv/src/mv.rs | 2 +- tests/by-util/test_mv.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index d3a6d2ed0..ba6f2198a 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -420,7 +420,7 @@ fn rename( OverwriteMode::NoClobber => return Ok(()), OverwriteMode::Interactive => { if !prompt_yes!("overwrite {}?", to.quote()) { - return Ok(()); + return Err(io::Error::new(io::ErrorKind::Other, "")); } } OverwriteMode::Force => {} diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index c5f930a2b..ffdff83dd 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -165,7 +165,7 @@ fn test_mv_interactive() { .arg(file_a) .arg(file_b) .pipe_in("n") - .succeeds() + .fails() .no_stdout(); assert!(at.file_exists(file_a)); From d0a4059f34bb078e86b8eb07d378f02a0f0b05f6 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 25 Mar 2023 11:14:15 +0100 Subject: [PATCH 2/4] cp -i: adjust the behavior to match the GNU change Just like mv Note that cp -i -u won't show the overwrite question Matches the change upstream 7a69df88999bedd8e9fccf9f3dfa9ac6907fab66 --- src/uu/cp/src/cp.rs | 7 ++++++- tests/by-util/test_cp.rs | 25 ++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 234289564..80540d222 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -78,6 +78,7 @@ quick_error! { StripPrefixError(err: StripPrefixError) { from() } /// Result of a skipped file + /// Currently happens when "no" is selected in interactive mode Skipped { } /// Result of a skipped file @@ -1018,7 +1019,11 @@ fn show_error_if_needed(error: &Error) -> bool { // When using --no-clobber, we don't want to show // an error message Error::NotAllFilesCopied => (), - Error::Skipped => (), + Error::Skipped => { + // touch a b && echo "n"|cp -i a b && echo $? + // should return an error from GNU 9.2 + return true; + } _ => { show_error!("{}", error); return true; diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index ca913adb5..723f2fab9 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -234,6 +234,16 @@ fn test_cp_arg_update_interactive() { .no_stderr(); } +#[test] +fn test_cp_arg_update_interactive_error() { + new_ucmd!() + .arg(TEST_HELLO_WORLD_SOURCE) + .arg(TEST_HOW_ARE_YOU_SOURCE) + .arg("-i") + .fails() + .no_stdout(); +} + #[test] fn test_cp_arg_interactive() { let (at, mut ucmd) = at_and_ucmd!(); @@ -241,11 +251,24 @@ fn test_cp_arg_interactive() { at.touch("b"); ucmd.args(&["-i", "a", "b"]) .pipe_in("N\n") - .succeeds() + .fails() .no_stdout() .stderr_is("cp: overwrite 'b'? "); } +#[test] +fn test_cp_arg_interactive_update() { + // -u -i won't show the prompt to validate the override or not + // Therefore, the error code will be 0 + let (at, mut ucmd) = at_and_ucmd!(); + at.touch("a"); + at.touch("b"); + ucmd.args(&["-i", "-u", "a", "b"]) + .pipe_in("N\n") + .succeeds() + .no_stdout(); +} + #[test] #[cfg(target_os = "linux")] fn test_cp_arg_link() { From 9d54ed02a8752eb0f1f0d38df785681a958ce889 Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Sat, 25 Mar 2023 11:21:39 +0100 Subject: [PATCH 3/4] ln -i: adjust the behavior to match the GNU change Just like mv & cp Matches the change upstream 7a69df88999bedd8e9fccf9f3dfa9ac6907fab66 --- src/uu/ln/src/ln.rs | 2 +- tests/by-util/test_ln.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/uu/ln/src/ln.rs b/src/uu/ln/src/ln.rs index c583aac1e..94117d0ed 100644 --- a/src/uu/ln/src/ln.rs +++ b/src/uu/ln/src/ln.rs @@ -392,7 +392,7 @@ fn link(src: &Path, dst: &Path, settings: &Settings) -> UResult<()> { OverwriteMode::NoClobber => {} OverwriteMode::Interactive => { if !prompt_yes!("overwrite {}?", dst.quote()) { - return Ok(()); + return Err(LnError::SomeLinksFailed.into()); } if fs::remove_file(dst).is_ok() {}; diff --git a/tests/by-util/test_ln.rs b/tests/by-util/test_ln.rs index 0f7241445..3be07c4d7 100644 --- a/tests/by-util/test_ln.rs +++ b/tests/by-util/test_ln.rs @@ -116,7 +116,7 @@ fn test_symlink_interactive() { .ucmd() .args(&["-i", "-s", file, link]) .pipe_in("n") - .succeeds() + .fails() .no_stdout(); assert!(at.file_exists(file)); From aa4101fe2f60ab9cca77fed9f1a8973ad6600269 Mon Sep 17 00:00:00 2001 From: Daniel Hofstetter Date: Sun, 26 Mar 2023 12:18:26 +0200 Subject: [PATCH 4/4] ln: use "replace" in interactive mode GNU ln uses "replace" instead of "overwrite" --- src/uu/ln/src/ln.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uu/ln/src/ln.rs b/src/uu/ln/src/ln.rs index 94117d0ed..bfff8d3eb 100644 --- a/src/uu/ln/src/ln.rs +++ b/src/uu/ln/src/ln.rs @@ -391,7 +391,7 @@ fn link(src: &Path, dst: &Path, settings: &Settings) -> UResult<()> { match settings.overwrite { OverwriteMode::NoClobber => {} OverwriteMode::Interactive => { - if !prompt_yes!("overwrite {}?", dst.quote()) { + if !prompt_yes!("replace {}?", dst.quote()) { return Err(LnError::SomeLinksFailed.into()); }