msys2 / msys2/msys2-runtime

Copying and moving a symlink to another FS fails if the target is relative

Open
#189 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

symlinks
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

  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

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.