diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index a884f114d26..766dcf32c63 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -2304,7 +2304,7 @@ fn copy_file( } handle_existing_dest(source, dest, options, source_in_command_line, copied_files)?; if are_hardlinks_to_same_file(source, dest) { - if options.copy_mode == CopyMode::Copy && options.backup != BackupMode::NoBackup { + if options.copy_mode == CopyMode::Copy { return Ok(()); } if options.copy_mode == CopyMode::Link && (!source_is_symlink || !dest_is_symlink) { diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 9a24792b0c1..72eddfd9f9a 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -4675,6 +4675,7 @@ fn test_cp_no_dereference_attributes_only_with_symlink() { /// contains the test for cp when the source and destination points to the same file mod same_file { + use std::os::unix::fs::MetadataExt; use uutests::util::TestScenario; use uutests::util_name; @@ -5594,6 +5595,26 @@ mod same_file { assert_eq!(FILE_NAME, at.resolve_link(hardlink_to_symlink)); assert_eq!(at.read(FILE_NAME), CONTENTS); } + + #[test] + fn test_hardlink_of_symlink_to_hardlink_of_same_symlink_with_option_no_deref() { + let scene = TestScenario::new(util_name!()); + let at = &scene.fixtures; + let hardlink1 = "hardlink_to_symlink_1"; + let hardlink2 = "hardlink_to_symlink_2"; + at.write(FILE_NAME, CONTENTS); + at.symlink_file(FILE_NAME, SYMLINK_NAME); + at.hard_link(SYMLINK_NAME, hardlink1); + at.hard_link(SYMLINK_NAME, hardlink2); + let ino = at.symlink_metadata(hardlink1).ino(); + assert_eq!(ino, at.symlink_metadata(hardlink2).ino()); // Sanity check + scene.ucmd().args(&["-P", hardlink1, hardlink2]).succeeds(); + assert!(at.file_exists(FILE_NAME)); + assert!(at.symlink_exists(SYMLINK_NAME)); + // If hardlink a and b point to the same symlink, then cp a b doesn't create a new file + assert_eq!(ino, at.symlink_metadata(hardlink1).ino()); + assert_eq!(ino, at.symlink_metadata(hardlink2).ino()); + } } // the following tests are for how the cp should behave when the source is a symlink