From 2789885648053e1ff1fe9c745dddefe0a5f2840b Mon Sep 17 00:00:00 2001 From: tommady Date: Wed, 27 Sep 2023 19:16:10 +0800 Subject: [PATCH] cp: fix cp -dR --no-preserve=links d c should have different inodes (#5320) * fix issue 5308 --- src/uu/cp/src/cp.rs | 38 ++++++++++++++++++++++++-------------- tests/by-util/test_cp.rs | 2 +- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 05261c22f..b6270719c 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -931,23 +931,33 @@ impl Options { }; // Parse attributes to preserve - let attributes = if let Some(attribute_strs) = matches.get_many::(options::PRESERVE) - { - if attribute_strs.len() == 0 { + let mut attributes = + if let Some(attribute_strs) = matches.get_many::(options::PRESERVE) { + if attribute_strs.len() == 0 { + Attributes::DEFAULT + } else { + Attributes::parse_iter(attribute_strs)? + } + } else if matches.get_flag(options::ARCHIVE) { + // --archive is used. Same as --preserve=all + Attributes::ALL + } else if matches.get_flag(options::NO_DEREFERENCE_PRESERVE_LINKS) { + Attributes::LINKS + } else if matches.get_flag(options::PRESERVE_DEFAULT_ATTRIBUTES) { Attributes::DEFAULT } else { - Attributes::parse_iter(attribute_strs)? + Attributes::NONE + }; + + // handling no-preserve options and adjusting the attributes + if let Some(attribute_strs) = matches.get_many::(options::NO_PRESERVE) { + if attribute_strs.len() > 0 { + let no_preserve_attributes = Attributes::parse_iter(attribute_strs)?; + if matches!(no_preserve_attributes.links, Preserve::Yes { .. }) { + attributes.links = Preserve::No; + } } - } else if matches.get_flag(options::ARCHIVE) { - // --archive is used. Same as --preserve=all - Attributes::ALL - } else if matches.get_flag(options::NO_DEREFERENCE_PRESERVE_LINKS) { - Attributes::LINKS - } else if matches.get_flag(options::PRESERVE_DEFAULT_ATTRIBUTES) { - Attributes::DEFAULT - } else { - Attributes::NONE - }; + } #[cfg(not(feature = "feat_selinux"))] if let Preserve::Yes { required } = attributes.context { diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index afac4cd3a..1ce74572d 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -1494,7 +1494,7 @@ fn test_cp_preserve_links_case_5() { let metadata_a = std::fs::metadata(at.subdir.join("c").join("a")).unwrap(); let metadata_b = std::fs::metadata(at.subdir.join("c").join("b")).unwrap(); - assert_eq!(metadata_a.ino(), metadata_b.ino()); + assert_ne!(metadata_a.ino(), metadata_b.ino()); } }