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!
