On 10/20/2011 01:47 PM, Paul Eggert wrote:
On 10/20/11 10:38, Eric Blake wrote:
POSIX is clear that attempts to rmdir() a directory that still has open
descriptors may fail.
Hmm, that's news to me. And on the contrary, the spec
<http://pubs.opengroup.org/onlinepubs/9699919799/functions/rmdir.html>
explicitly talks about what rmdir() does when there are open descriptors:
"If one or more processes have the directory open when the last link is
removed,
the dot and dot-dot entries, if present, shall be removed before rmdir()
returns
and no new entries may be created in the directory, but the directory shall
not
be removed until all references to the directory are closed."
which very much sounds like rmdir() is supposed to succeed in this case.
Also, there's no entry for this situation under the "may fail" section
of ERRORS. And there's longstanding Unix tradition that you can unlink
a file that you have an open file descriptor to, which suggests that
rmdir() should do likewise.
That's because it's a shall fail, not a may fail error:
[EBUSY]
The directory to be removed is currently in use by the system or some
process and the implementation considers this to be an error.
So, if this is a problem under Cygwin, it's probably better to handle it
in the rmdir() wrapper that deals with Cygwin and file descriptors.
It's more than just cygwin. And while cygwin _is_ working around this
in many cases (cygwin is going to some rather extreme lengths for NTFS
and NFS, for example), it only works on a per-filesystem basis (the
latest bug is that a Novell device driver, exposing the NWFS file
system, has bugs in its mapping to Windows system calls that are
preventing cygwin's normal workarounds from working). But even when
cygwin can work around it, it is expensive (it involves reopening the
handle multiple times, with varying level of permission requests, to see
if the file is previously opened in sharing mode, and depending on that
result, temporarily moving the file to the recycle bin so that it will
disappear when the last handle closes); whereas fixing coreutils to do
things in the correct order in the first place would make the overall rm
process faster because it isn't wasting time on corner case file
shuffling for a directory that is being deleted in the first place.
At any rate, this is a regression introduced by coreutils 8.0, when rm
switched to fts(). Prior to that point, coreutils used the correct
ordering, where rmdir() was not attempted until after the close(); and
the Cygwin report demonstrated that coreutils 7.0 worked on NWFS where
coreutils 8.x fails.
--
Eric Blake ebl...@redhat.com +1-801-349-2682
Libvirt virtualization library http://libvirt.org