[darcs-users] DeleteFile on Windows (was: Re: hashed-storage work now merged in (woo!))

Petr Rockai me at mornfall.net
Thu Oct 8 22:17:30 UTC 2009


Eric Kow <kowey at darcs.net> writes:
> So you may have noticed me saying this in a couple of recent threads.
> Petr Ročkai's hashed-storage work from his 2009 Google Summer of Code
> project has been merged!
> I thought I would take a few moments to give everybody an overview of
> how this work benefits us, and where we'll be going in the future.

before we can really celebrate, there're some issues that we need to sort
out. Unfortunately, darcs has regressed a fair bit on win32, as our current red
Windows slave witnesses. I can reproduce some of these failures on my
virtualboxed Windows XP, but not even all of them. It won't be easy to fix,
either. I suspect part of the problem is in more aggressive mmapping -- in
fact, we now mmap pristine on Windows, which was never before the case, as far
as I can tell.

The mmap package in its current incarnation uses C finalizers for mmap'd areas,
but that doesn't seem to be enough to get the mappings finalized soon enough
(with regards to deleting files in pristine).

So my current idea (already discussed marginally during darcs-hs review, but I
have more specifics now) is to create a small "trashfile" hackage library that
exports these few things:

-- | Set up a place (directory) where we can move files that cannot be deleted
-- due to being open on win32. On POSIX, this is a noop. If there are any files
-- in this directory, they will be immediately removed (barring permission
-- problems).
setTrashLocation :: FilePath -> IO ()
setTrashLocation = undefined

-- | Remove a file. On POSIX, this is alias to removeFile. On Windows, we try
-- to removeFile first, but if that fails with permission problems (probably
-- still open), we instead move that file into the trash location set using
-- "setTrashLocation".
trashFile :: FilePath -> IO ()
trashFile = undefined

-- | Try to clean up any garbage left in the trash location. Could be called at
-- the end of your program to reduce any mess left on Win32 systems. Optional.
cleanTrash :: IO ()
cleanTrash = undefined

I believe this should be more or less enough for darcs and hashed-storage. We
can make trashFile an alias to removeFile when setTrashLocation was not called
-- that way, hashed-storage can use trashFile safely, and in programs that call
setTrashLocation, it will employ the win32 workaround transparently (with
others, it'll work the same as it works now, more or less).

Then, darcs can call setTrashLocation "_darcs/trash" at startup and cleanTrash
before exit and we should (hopefully) get rid of all those pesky DeleteFile:
Permission denied issues.

I agree this is sort of hairy, but it lets us have POSIX file deletion
semantics (sort of) which are actually quite more powerful than what Windows
allows (this is very useful when rebuilding the index, eg.).

(The alternative would be to use a native "trash" API of win32, if there is any
-- but I reckon that windows by default does not delete files but moves them to
trash, so there *may* be some sort of API for doing just that?)


More information about the darcs-users mailing list