uutils / uutils/coreutils

cp: when doing hardlink copy of symlink, should replace a technically-different symlink

Open
#6,531 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

U - cp
Dominant language
Rust
Stars
24.1k
Forks
2k
Avg merge
1d 5h
Merged PRs (30d)
365

Description

Let's say we have a regular file regularfile, and two symlinks to it, symlink and hop. Then we have an additional symlink indirect_symlink which points to hop. For most intents and purposes, indirect_symlink points to regularfile, but technically it doesn't, and this difference is visible in ls and would also change completely if hop ever points somewhere else or becomes a (different) regular file.

Now cp should replace indirect_symlink by a hardlink-copy of symlink, but our current implementation says "Eh, everything is fine!" and does nothing, which is just wrong. The -v in the example below is just for illustration.

$ ln -s README.md symlink
$ ln -s README.md hop
$ rm -f indirect_symlink && ln -s hop indirect_symlink && ls -1i README.md symlink hop indirect_symlink && cp -vlP symlink indirect_symlink && ls -1i README.md symlink hop indirect_symlink
20092600 README.md
20074249 hop
20074347 indirect_symlink
20074037 symlink
removed 'indirect_symlink'
'symlink' -> 'indirect_symlink'
20092600 README.md
20074249 hop
20074037 indirect_symlink
20074037 symlink
$ readlink indirect_symlink  # Points directly to README.md
README.md
$ rm -f indirect_symlink && ln -s hop indirect_symlink && ls -1i README.md symlink hop indirect_symlink && cargo run -q cp -vlP symlink indirect_symlink && ls -1i README.md symlink hop indirect_symlink
20092600 README.md
20074249 hop
20074347 indirect_symlink
20074037 symlink
20092600 README.md
20074249 hop
20074347 indirect_symlink
20074037 symlink
$ readlink indirect_symlink  # It didn't even get rewritten!
hop

Found while reading https://github.com/uutils/coreutils/pull/6496, but only remotely related.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the reported cp -vlP symlink indirect_symlink behavior from the issue, then inspect the cp implementation and the related discussion in pull request 6496. The fix is done when an indirect symlink is replaced by a hardlink-copy of the source symlink, while the command’s existing behavior remains intact.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.