Skip to content

Commit 2789885

Browse files
authored
cp: fix cp -dR --no-preserve=links d c should have different inodes (#5320)
* fix issue 5308
1 parent df584f6 commit 2789885

2 files changed

Lines changed: 25 additions & 15 deletions

File tree

src/uu/cp/src/cp.rs

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -931,23 +931,33 @@ impl Options {
931931
};
932932

933933
// Parse attributes to preserve
934-
let attributes = if let Some(attribute_strs) = matches.get_many::<String>(options::PRESERVE)
935-
{
936-
if attribute_strs.len() == 0 {
934+
let mut attributes =
935+
if let Some(attribute_strs) = matches.get_many::<String>(options::PRESERVE) {
936+
if attribute_strs.len() == 0 {
937+
Attributes::DEFAULT
938+
} else {
939+
Attributes::parse_iter(attribute_strs)?
940+
}
941+
} else if matches.get_flag(options::ARCHIVE) {
942+
// --archive is used. Same as --preserve=all
943+
Attributes::ALL
944+
} else if matches.get_flag(options::NO_DEREFERENCE_PRESERVE_LINKS) {
945+
Attributes::LINKS
946+
} else if matches.get_flag(options::PRESERVE_DEFAULT_ATTRIBUTES) {
937947
Attributes::DEFAULT
938948
} else {
939-
Attributes::parse_iter(attribute_strs)?
949+
Attributes::NONE
950+
};
951+
952+
// handling no-preserve options and adjusting the attributes
953+
if let Some(attribute_strs) = matches.get_many::<String>(options::NO_PRESERVE) {
954+
if attribute_strs.len() > 0 {
955+
let no_preserve_attributes = Attributes::parse_iter(attribute_strs)?;
956+
if matches!(no_preserve_attributes.links, Preserve::Yes { .. }) {
957+
attributes.links = Preserve::No;
958+
}
940959
}
941-
} else if matches.get_flag(options::ARCHIVE) {
942-
// --archive is used. Same as --preserve=all
943-
Attributes::ALL
944-
} else if matches.get_flag(options::NO_DEREFERENCE_PRESERVE_LINKS) {
945-
Attributes::LINKS
946-
} else if matches.get_flag(options::PRESERVE_DEFAULT_ATTRIBUTES) {
947-
Attributes::DEFAULT
948-
} else {
949-
Attributes::NONE
950-
};
960+
}
951961

952962
#[cfg(not(feature = "feat_selinux"))]
953963
if let Preserve::Yes { required } = attributes.context {

tests/by-util/test_cp.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1494,7 +1494,7 @@ fn test_cp_preserve_links_case_5() {
14941494
let metadata_a = std::fs::metadata(at.subdir.join("c").join("a")).unwrap();
14951495
let metadata_b = std::fs::metadata(at.subdir.join("c").join("b")).unwrap();
14961496

1497-
assert_eq!(metadata_a.ino(), metadata_b.ino());
1497+
assert_ne!(metadata_a.ino(), metadata_b.ino());
14981498
}
14991499
}
15001500

0 commit comments

Comments
 (0)