rm/unlink: Unable to delete hard links to itself on Windows
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 24.1k
- Forks
- 2k
- Avg merge
- 1d 5h
- Merged PRs (30d)
- 365
Description
I think this could be considered a bug, but I am not too acquainted with the inner workings of it all to be able to say for sure.
I was just installing coreutils and creating some hard links to have them in PATH on Windows as they are more convenient for me, one of them had a typo and instead of renaming the file I chose to delete and link again, that's when I stumbled upon it. rm is able to delete hard links (and symbolic ones too) just fine, unless that link is to itself.
This would be an example output of it happening with the current release (0.0.26):
- Multicall binary creates hard link to itself.
- Same multicall binary tries to remove the link (fails, exits with 1).
- Same outcome but trying to unlink instead.
- Different multicall binary tries to remove the link (succeeds).
$ coreutils-gnu.exe ln coreutils-gnu.exe hard.exe
$ coreutils-gnu.exe rm hard.exe
rm: cannot remove 'hard.exe': Permission denied
$ coreutils-gnu.exe unlink hard.exe
unlink: cannot unlink 'hard.exe': Permission denied
$ coreutils-msvc.exe rm hard.exe
$
It doesn't matter that the link was created using coreutils or natively via mklink for example, the condition for failure seems to be the hard link being to binary executing rm itself (and the MSVC build exhibits the same behavior, of course).
I performed the same steps on Linux using the binary release for 0.0.26, but the result was expected, the hard link was removed.
PS. ls -l doesn't show the correct number of references for hardlinks on Windows, but that may just be by design, it would require native API calls like CreateFile() to get a handle and GetFileInformationByHandle() to get to it, so it would need conditional code based on the platform it's built for.
Contributor guide
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 reported sequence on Windows with rm, unlink, and a hard link to the executing multicall binary, then compare it with removal by a different binary and with Linux behavior. Start from the rm and unlink entry points; done means both commands can remove the self-referential hard link without the reported permission-denied failure.
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