[RFC] unlink() implementation

Pierre A. Humblet Pierre.Humblet@ieee.org
Fri Oct 10 23:17:00 GMT 2003

At 10:18 PM 10/10/2003 +0200, Corinna Vinschen wrote:
>the discussion in the Cygwin ML about removing files led Chris and me
>to some more discussing the implementation of unlink() and some more
>tests.  Basically, the description in MSDN about DeleteFile is wrong.
>MSDN claims
>  "In the Windows 95 and 98 environment, the DeleteFile function
>   deletes a file even if it is open unless the file has been opened
>   with the FILE_SHARE_DELETE flag."

Right, it's wrong.

>First, a file which is open in the same or another process can not
>be deleted.  Second, adding the FILE_SHARE_DELETE flag to CreateFile
>calls results in a failing CreateFile.  This, OTOH, matches the
>MSDN description of CreateFile:
>  "FILE_SHARE_DELETE [...] Windows 95/98/Me: This flag is not supported."


>Third, even FILE_FLAG_DELETE_ON_CLOSE has no effect on 9x, even though
>MSDN does not mention any problem with that flag on 9x/Me.

If that was the case then the 1.5.5 rm wouldn't work on 9x even with
files that are not opened, and there would be a lot more complaints!

17493  736406 [main] rm 830863 unlink: _unlink (c:\home\pierre\xx)
 6673  743079 [main] rm 830863 unlink: 1 = CloseHandle (0xD8)
 1997  745076 [main] rm 830863 unlink: CreateFile
  691  745767 [main] rm 830863 unlink: 0 = unlink (xx)
and xx is really gone.

If the file is already opened, CreateFile (FILE_FLAG_DELETE_ON_CLOSE)
incorrectly appears to succeed if the file was opened for reading, 
but fails if it was opened for writing.
Without the FILE_SHARE_READ, it always fails if the file is already opened,
which is what we want (FILE_SHARE_READ might be needed for some other
reason, although I think it's a relic of the past).

In other words, on 9x FILE_FLAG_DELETE_ON_CLOSE (without FILE_SHARE_XX)
seems to work exactly as DeleteFile.
Given the mixed experience with FILE_FLAG_DELETE_ON_CLOSE, I'd rather use

>So, while the implementation of unlink() works fine on NT systems
>(we seem to have even more working code than necessary) the implementation
>looks a bit cheerless on 9x/Me in terms of POSIX-like behaviour:
>  DeleteFile?  Works if the file isn't open, otherwise it fails.
>  If it fails, the file is stored in the delqueue.  This results
>  in the file being deleted on exit... if the file hasn't been opened
>  by another process.

It's deleted on close (if it happens before exit), .. if the file hasn't
been [re]opened by another [or the same] process.

>The delqueue is (to say it with cgf) a horrible kludge which we're
>trying to avoid as far as possible.


>So, I would like to ask you folks, what you think about the idea,
>to try to move the file into the recycle bin, if delete file fails.
>The whole implementation then looks like this, every step only tried
>if the step before failed:
>Step 1 (Only on NT):
>    Try CreateFile(FILE_FLAG_DELETE_ON_CLOSE)/CloseHandle();
>Step 2:
>    Try DeleteFile();

Are there cases where 1 fails on NT when 2 works? If not, skip 2.
Does DeleteFile() work at all with opened file on NT?
There must be a reason why our ancestors went to the trouble of 
implementing 1.

>Step 3:
>    Try SHFileOperation(FO_DELETE)  // moves to Recycle Bin

I cannot place opened files in the wastebasket, so I doubt that this
would work when we need it.
I would be surprised if early Cygwin developers hadn't tried this.

>Step 4:
>    Store in delqueue.


>Besides the examination, that we could drop step 1 on NT, what do
>people think about the idea, to try to move the file to the
>recycle bin if a DeleteFile failed?  Note that I didn't actually
>*test* it, but I'd like to know, if I'm something missing which
>invalidates the idea.  Any really bad caveat?

With the exception of the recent glitch, I see no complaints about 
unlink on 9x, although it may require work when porting applications 
(I have had that experience with xfig, the problem is ".. if the file
hasn't been [re]opened by another [or the same] process" )

Still, if you can make it work, it's worth a try. 


More information about the Cygwin-developers mailing list