On 09/04/2012 08:02 AM, Jim Meyering wrote:
> I'm not 100% sold on the idea that that final unlinkat
> call should be creating a dangling symlink (i.e., by removing
> the directory to which "s" points).
But that's what rmdir() and the rmdir command
are supposed to do. That much, at least, is pretty clearly
specified by POSIX 2008.
But now I see that coreutils rmdir doesn't do that:
$ mkdir a
$ ln -s a b
$ rmdir b/
rmdir: failed to remove 'b/': Not a directory
Solaris 10 rmdir gets it right. Interestingly enough,
Solaris 10's port of coreutils rmdir (/opt/sfw/bin/rmdir)
also gets it right: it executes rmdir("b/"),
which removes the directory. This is coreutils 5.93,
so I assume at some point there was a regression?
A bit more investigation shows that rmdir("b/")
fails on Linux 3.2.0, succeeds on Solaris 10, but
fails on Solaris 11! Curiouser and curiouser. This
means the Solaris 11 rmdir command agrees with GNU/Linux
and they both disagree with POSIX and with Solaris 10.
The problem also affects other commands. For example,
POSIX says this should work:
$ mkdir a
$ ln -s a b
$ mv b/ c
and should rename a to c. It does work, on Solaris 11,
but with coreutils it fails and reports
mv: cannot move 'b/' to 'c': Not a directory