Copying and moving a symlink to another FS fails if the target is relative
Nobody has claimed this yet.
- Dominant language
- C
- Stars
- 240
- Forks
- 60
- Avg merge
- 2d 3h
- Merged PRs (30d)
- 1
Description
This happens on a recently updated MSYS2:
$ uname -a
MSYS_NT-10.0-19044 DESKTOP-O7JE7JE 3.4.10.x86_64 2023-12-22 10:06 UTC x86_64 Msys
IOW, if after the operation a symlink would become broken (by target being relative), it won't cross the FS boundaries:
DEST_DIR=/tmp/destination
export DEST_DIR
echo The content > original
ln -sv original symlink-1
ln -sv original symlink-2
mkdir -pv ${DEST_DIR}
cp -Pv symlink-1 ${DEST_DIR}
mv -v symlink-2 ${DEST_DIR}
Actual output:
'symlink-1' -> 'original'
'symlink-2' -> 'original'
mkdir: created directory '/tmp/destination'
'symlink-1' -> '/tmp/destination/symlink-1'
cp: cannot create symbolic link '/tmp/destination/symlink-1': No such file or directory
copied 'symlink-2' -> '/tmp/destination/symlink-2'
mv: cannot create symbolic link '/tmp/destination/symlink-2': No such file or directory
A bit more verbose testing: https://asciinema.org/a/632681
If the destination dir is on the same FS, only copying is broken. Moving the symlink works fine:
'symlink-1' -> 'original'
'symlink-2' -> 'original'
mkdir: created directory '/tmp/destination'
'symlink-1' -> '/tmp/destination/symlink-1'
cp: cannot create symbolic link '/tmp/destination/symlink-1': No such file or directory
renamed 'symlink-2' -> '/tmp/destination/symlink-2'
Expected output:
'symlink-1' -> 'original'
'symlink-2' -> 'original'
mkdir: created directory '/tmp/destination'
'symlink-1' -> '/tmp/destination/symlink-1'
copied 'symlink-2' -> '/tmp/destination/symlink-2'
removed 'symlink-2'
If the target name is in an absolute format (IOW, it won't get broken after occurring in another dir), everything works across the FS just fine:
'symlink-1' -> '/D/bandom/original'
'symlink-2' -> '/D/bandom/original'
mkdir: created directory '/tmp/destination'
'symlink-1' -> '/tmp/destination/symlink-1'
copied 'symlink-2' -> '/tmp/destination/symlink-2'
removed 'symlink-2'
I tested that on fairly recent Cygwin too:
$ uname -a
CYGWIN_NT-10.0-19044 DESKTOP-O7JE7JE 3.4.10-1.x86_64 2023-11-29 12:12 UTC x86_64 Cygwin
It mostly works:
$ bash band.sh
'symlink-1' -> 'original'
'symlink-2' -> 'original'
mkdir: created directory '/tmp/destination'
'symlink-1' -> '/tmp/destination/symlink-1'
copied 'symlink-2' -> '/tmp/destination/symlink-2'
mv: listing attributes of 'symlink-2': Permission denied
removed 'symlink-2'
... with the following warning being added:
mv: listing attributes of '...': Permission denied
Please excuse me if this belongs to msys2/MSYS2-packages.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the issue with the provided MSYS2 shell commands for copying and moving relative-target symlinks across filesystems, then compare the same cases on the same filesystem and with absolute targets. Trace the runtime's symlink handling for cp and mv; done means the expected copy and move outputs succeed without the reported errors while preserving the relative target.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c
- Domain
- operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100