diff --git a/src/uu/cp/src/cp.rs b/src/uu/cp/src/cp.rs index 7207673a5..3b02c2c58 100644 --- a/src/uu/cp/src/cp.rs +++ b/src/uu/cp/src/cp.rs @@ -2108,6 +2108,10 @@ fn copy_file( .into()); } + if options.verbose { + print_verbose_output(options.parents, progress_bar, source, dest); + } + if options.preserve_hard_links() { // if we encounter a matching device/inode pair in the source tree // we can arrange to create a hard link between the corresponding names @@ -2121,10 +2125,6 @@ fn copy_file( }; } - if options.verbose { - print_verbose_output(options.parents, progress_bar, source, dest); - } - // Calculate the context upfront before canonicalizing the path let context = context_for(source, dest); let context = context.as_str(); diff --git a/tests/by-util/test_cp.rs b/tests/by-util/test_cp.rs index 3b4ec74f7..ca592f6fd 100644 --- a/tests/by-util/test_cp.rs +++ b/tests/by-util/test_cp.rs @@ -608,6 +608,36 @@ fn test_cp_arg_link_with_same_file() { assert!(at.file_exists(file)); } +#[test] +#[cfg(target_os = "linux")] +fn test_cp_verbose_preserved_link_to_dir() { + use std::os::linux::fs::MetadataExt; + + let (at, mut ucmd) = at_and_ucmd!(); + let file = "file"; + let hardlink = "hardlink"; + let dir = "dir"; + let dst_file = "dir/file"; + let dst_hardlink = "dir/hardlink"; + + at.touch(file); + at.hard_link(file, hardlink); + at.mkdir(dir); + + ucmd.args(&["-d", "--verbose", file, hardlink, dir]) + .succeeds() + .stdout_is("'file' -> 'dir/file'\n'hardlink' -> 'dir/hardlink'\n"); + + assert!(at.file_exists(dst_file)); + assert!(at.file_exists(dst_hardlink)); + assert_eq!(at.metadata(dst_file).st_nlink(), 2); + assert_eq!(at.metadata(dst_hardlink).st_nlink(), 2); + assert_eq!( + at.metadata(dst_file).st_ino(), + at.metadata(dst_hardlink).st_ino() + ); +} + #[test] fn test_cp_arg_symlink() { let (at, mut ucmd) = at_and_ucmd!();