Skip to content

Commit

Permalink
Merge pull request #5731 from cakebaker/cp_backup_with_dest_a_symlink
Browse files Browse the repository at this point in the history
cp: fix backup of destination symlink
  • Loading branch information
sylvestre committed Dec 27, 2023
2 parents bf26eda + 0701f53 commit 04a7f9c
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 1 deletion.
6 changes: 5 additions & 1 deletion src/uu/cp/src/cp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1496,7 +1496,11 @@ fn context_for(src: &Path, dest: &Path) -> String {
/// Implements a simple backup copy for the destination file.
/// TODO: for the backup, should this function be replaced by `copy_file(...)`?
fn backup_dest(dest: &Path, backup_path: &Path) -> CopyResult<PathBuf> {
fs::copy(dest, backup_path)?;
if dest.is_symlink() {
fs::rename(dest, backup_path)?;
} else {
fs::copy(dest, backup_path)?;
}
Ok(backup_path.into())
}

Expand Down
21 changes: 21 additions & 0 deletions tests/by-util/test_cp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,27 @@ fn test_cp_arg_backup() {
);
}

#[test]
fn test_cp_arg_backup_with_dest_a_symlink() {
let (at, mut ucmd) = at_and_ucmd!();
let source = "source";
let source_content = "content";
let symlink = "symlink";
let original = "original";
let backup = "symlink~";

at.write(source, source_content);
at.write(original, "original");
at.symlink_file(original, symlink);

ucmd.arg("-b").arg(source).arg(symlink).succeeds();

assert!(!at.symlink_exists(symlink));
assert_eq!(source_content, at.read(symlink));
assert!(at.symlink_exists(backup));
assert_eq!(original, at.resolve_link(backup));
}

#[test]
fn test_cp_arg_backup_with_other_args() {
let (at, mut ucmd) = at_and_ucmd!();
Expand Down

0 comments on commit 04a7f9c

Please sign in to comment.