1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-29 03:57:44 +00:00

Do not dereference symlink even when dangling (fix #3364)

Fixes an issue with cp not copying symlinks in spite of the -P  (no dereference option)
Fix issue #3364

Performance improvements

Avoid useless read from metadata and reuse previous dest information

Signed-off-by: anastygnome <noreplygit@protonmail.com>
This commit is contained in:
anastygnome 2022-05-02 08:28:23 +02:00
parent 6747e7261e
commit badf947f8a
No known key found for this signature in database
GPG key ID: 5EFFB4485F9B4317

View file

@ -992,7 +992,9 @@ fn copy_directory(
} }
// if no-dereference is enabled and this is a symlink, copy it as a file // if no-dereference is enabled and this is a symlink, copy it as a file
if !options.dereference && fs::symlink_metadata(root).unwrap().file_type().is_symlink() { if !options.dereference && fs::symlink_metadata(root).unwrap().file_type().is_symlink()
// replace by is_symlink in rust>=1.58
{
return copy_file(root, target, options, symlinked_files); return copy_file(root, target, options, symlinked_files);
} }
@ -1036,6 +1038,7 @@ fn copy_directory(
{ {
let p = or_continue!(path); let p = or_continue!(path);
let is_symlink = fs::symlink_metadata(p.path())?.file_type().is_symlink(); let is_symlink = fs::symlink_metadata(p.path())?.file_type().is_symlink();
// replace by is_symlink in rust >=1.58
let path = current_dir.join(&p.path()); let path = current_dir.join(&p.path());
let local_to_root_parent = match root_parent { let local_to_root_parent = match root_parent {
@ -1288,7 +1291,7 @@ fn copy_file(
// Fail if dest is a dangling symlink or a symlink this program created previously // Fail if dest is a dangling symlink or a symlink this program created previously
if fs::symlink_metadata(dest) if fs::symlink_metadata(dest)
.map(|m| m.file_type().is_symlink()) .map(|m| m.file_type().is_symlink()) // replace by is_symlink in rust>=1.58
.unwrap_or(false) .unwrap_or(false)
{ {
if FileInformation::from_path(dest, false) if FileInformation::from_path(dest, false)
@ -1301,7 +1304,7 @@ fn copy_file(
dest.display() dest.display()
))); )));
} }
if !dest.exists() { if options.dereference && !dest.exists() {
return Err(Error::Error(format!( return Err(Error::Error(format!(
"not writing through dangling symlink '{}'", "not writing through dangling symlink '{}'",
dest.display() dest.display()
@ -1535,7 +1538,7 @@ fn copy_link(
} else { } else {
// we always need to remove the file to be able to create a symlink, // we always need to remove the file to be able to create a symlink,
// even if it is writeable. // even if it is writeable.
if dest.exists() { if dest.is_file() {
fs::remove_file(dest)?; fs::remove_file(dest)?;
} }
dest.into() dest.into()