uutils / coreutils

Cross-platform Rust rewrite of the GNU coreutils
https://uutils.github.io/
MIT License
17.61k stars 1.27k forks source link

cp: cannot copy attributes from one symlink to another #6533

Open BenWiederhake opened 3 months ago

BenWiederhake commented 3 months ago

Let's say we have a regular file, and two distinct symlinks pointing at it, owned by different users:

$ ln -s README.md symlink1
$ ln -s README.md symlink2
$ sudo chown -h root: symlink2
$ ls -l README.md symlink*
-rw-r--r-- 1 user user 7973 May  4 20:44 README.md
lrwxrwxrwx 1 user user    9 Jul  3 03:37 symlink1 -> README.md
lrwxrwxrwx 1 root root    9 Jul  3 03:37 symlink2 -> README.md

… then cp fails to handle --attributes-only correctly. There are two aspects to this, which may or may not be the same bug:

Aspect 1: Fails to notice that files are initially identical

$ cp --attributes-only -v symlink1 symlink2
cp: 'symlink1' and 'symlink2' are the same file
[$? = 1]
$ cargo run -q cp --attributes-only -v symlink1 symlink2
cp: cannot change attribute 'symlink2': Source file is a non regular file
[$? = 1]

Aspect 2: Fails consider that --attribute-only can be meaningful even on symlinks

$ cp -b --attributes-only -v symlink1 symlink2
'symlink1' -> 'symlink2' (backup: 'symlink2~')
$ ls -l README.md symlink*
-rw-r--r-- 1 user user 7973 May  4 20:44 README.md
lrwxrwxrwx 1 user user    9 Jul  3 03:37 symlink1 -> README.md
-rw-r--r-- 1 user user    0 Jul  3 03:42 symlink2
lrwxrwxrwx 1 root root    9 Jul  3 03:37 symlink2~ -> README.md
$ rm symlink2
$ mv symlink2~ symlink2  
$ cargo run -q cp -b --attributes-only -v symlink1 symlink2
cp: cannot change attribute 'symlink2': Source file is a non regular file
[$? = 1]

Found while reading #6496, but only remotely related.

pyoky commented 3 months ago

I'll take a look at this along with #6532 #6531 #6530