Skip to content

Commit d37f500

Browse files
dan-hipschmanBenWiederhake
authored andcommitted
cp: cp -P hardlink-to-symlink hardlink-to-same-symlink should noop
1 parent 771143a commit d37f500

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

src/uu/cp/src/cp.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2304,7 +2304,7 @@ fn copy_file(
23042304
}
23052305
handle_existing_dest(source, dest, options, source_in_command_line, copied_files)?;
23062306
if are_hardlinks_to_same_file(source, dest) {
2307-
if options.copy_mode == CopyMode::Copy && options.backup != BackupMode::NoBackup {
2307+
if options.copy_mode == CopyMode::Copy {
23082308
return Ok(());
23092309
}
23102310
if options.copy_mode == CopyMode::Link && (!source_is_symlink || !dest_is_symlink) {

tests/by-util/test_cp.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4675,6 +4675,7 @@ fn test_cp_no_dereference_attributes_only_with_symlink() {
46754675
/// contains the test for cp when the source and destination points to the same file
46764676
mod same_file {
46774677

4678+
use std::os::unix::fs::MetadataExt;
46784679
use uutests::util::TestScenario;
46794680
use uutests::util_name;
46804681

@@ -5594,6 +5595,26 @@ mod same_file {
55945595
assert_eq!(FILE_NAME, at.resolve_link(hardlink_to_symlink));
55955596
assert_eq!(at.read(FILE_NAME), CONTENTS);
55965597
}
5598+
5599+
#[test]
5600+
fn test_hardlink_of_symlink_to_hardlink_of_same_symlink_with_option_no_deref() {
5601+
let scene = TestScenario::new(util_name!());
5602+
let at = &scene.fixtures;
5603+
let hardlink1 = "hardlink_to_symlink_1";
5604+
let hardlink2 = "hardlink_to_symlink_2";
5605+
at.write(FILE_NAME, CONTENTS);
5606+
at.symlink_file(FILE_NAME, SYMLINK_NAME);
5607+
at.hard_link(SYMLINK_NAME, hardlink1);
5608+
at.hard_link(SYMLINK_NAME, hardlink2);
5609+
let ino = at.symlink_metadata(hardlink1).ino();
5610+
assert_eq!(ino, at.symlink_metadata(hardlink2).ino()); // Sanity check
5611+
scene.ucmd().args(&["-P", hardlink1, hardlink2]).succeeds();
5612+
assert!(at.file_exists(FILE_NAME));
5613+
assert!(at.symlink_exists(SYMLINK_NAME));
5614+
// If hardlink a and b point to the same symlink, then cp a b doesn't create a new file
5615+
assert_eq!(ino, at.symlink_metadata(hardlink1).ino());
5616+
assert_eq!(ino, at.symlink_metadata(hardlink2).ino());
5617+
}
55975618
}
55985619

55995620
// the following tests are for how the cp should behave when the source is a symlink

0 commit comments

Comments
 (0)