On 4/25/06, Mr. Shawn H. Corey <[EMAIL PROTECTED]> wrote:
> On Tue, 2006-25-04 at 16:41 -0500, JupiterHost.Net wrote:
> > althought technically any rm -rf (ven the shell itself) has a race
> > condition since it could clean out directory, move on and then, someone
> > adds a file between cleaning out the directory and its removal.
>
> Sorry, there is no such race condition in UNIX but there might be in
> other OSes. When you open a file in UNIX, you are sitting on the i-node,

[snip]

> Of course, like I said, this may not be true for other OSes. If you are
> writing a portable script, you should keep this in mind.

I can't think of a (reasonably modern) OS where you can still get a
true race condition--and by that I mean a real unrecoverable
lock-up--in this scenario. I think all inode/vnode operations are
atomic these days, even on Windows. I'm a little bit confused by
rmtree's warning, but I suspect they're using "race condition"
liberally.

There is, however, a potential for what Jup suggests on all OSes, even
though it shouldn't be a race condition, it should just be an error.
Unless you have kernel file locking, and lock the files and
directories before you delete them (something I'm pretty sure none of
the options discussed do), you can't guarantee that the directory's
link count won't change while you're in the process of deleting it.
That will cause the final call to rmdir(2) (on unix) to return
ENOTEMPTY, and you need to recover and rescan the directory, or fail
gracefully. It sounds like File::Path::rmtree() may have trouble with
this. I'm not sure about File::Copy::Recursive::pathrmdir().

There are also at least two other cases you need to watch out for,
both involving EBUSY. First, not all unices will let you delete the
root directory or cwd of a running process. Linux will, but it's not
POSIX and I think some BSDs will return EBUSY. And even on Linux, the
directory will be kept open even though rmdir() returned success, so
calling rmdir() on the parent will return EBUSY or ENOTEMPTY, I think,
untill the process finishes. The other time you'll see this is if the
directory you're trying to rmdir is a mount point. Even though it may
look empty rmdir() will return EBUSY until all processes rooted in the
mount point or its (former) subdirectories have exited or moved on,
even on Linux. Most people probably run into this more often with
umount than with rmdir, but they both exhibit similar behavior.

See the man pages for rmdir(2) and unlink(2) on your system for the
gorey details.

-- jay
--------------------------------------------------
This email and attachment(s): [  ] blogable; [ x ] ask first; [  ]
private and confidential

daggerquill [at] gmail [dot] com
http://www.tuaw.com  http://www.dpguru.com  http://www.engatiki.org

values of β will give rise to dom!

Reply via email to