monotone-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Monotone-devel] heads up: file system changes


From: Stephen Leake
Subject: Re: [Monotone-devel] heads up: file system changes
Date: Thu, 24 Sep 2009 23:45:13 -0400
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.2 (windows-nt)

Zack Weinberg <address@hidden> writes:

> On Wed, Sep 23, 2009 at 11:30 PM, Stephen Leake
> <address@hidden> wrote:
>> Daniel Atallah <address@hidden> writes:
>>> On Wed, Sep 23, 2009 at 07:30, Stephen Leake
>>> <address@hidden> wrote:
>>>> Zack Weinberg <address@hidden> writes:
>>>>
>>>> Why is do_remove in platform.hh? The unix implementation requires C90
>>>> 'remove'. Are we assuming C90 is not available on Windows? I assume
>>>> MinGW provides that (but maybe it doesn't?); do we really care about
>>>> any other compiler/runtime?
>>>
>>> remove() in the Windows CRT only will delete files, not directories:
>>> http://msdn.microsoft.com/en-us/library/2da4hk1d%28VS.80%29.aspx
>>
>> That's the same as Gnu libc:
>>
>>    Use `remove' to dissolve the association between a particular
>>    filename (the string at FILENAME) and the file it represents.
>>    After calling `remove' with a particular filename, you will no
>>    longer be able to open the file by that name.
>
> That's not the documentation I have for GNU libc ...

Sigh. I was quoting from libc.info, which is titled "The Red Hat
newlib C Library". I thought that was an implementation of the C
standard runtime; apparently not.

> http://www.gnu.org/software/libc/manual/html_node/Deleting-Files.html
> first describes unlink() [which does not work on directories] and
> rmdir() [which only works on directories] and then says
>
> — Function: int remove (const char *filename)
>
>     This is the ISO C function to remove a file. It works like unlink
> for files and like rmdir for directories. remove is declared in
> stdio.h.

That certainly makes sense. 

But if it's in stdio.h, doesn't that mean it's defined by the C
standard? So it should be the same on Win32? Hmm. Maybe that standard
allows this variance as "implementation defined". Yuck.

>> Right. But in this case, it is an implementation of the standard C
>> library.
>
> I checked - contra my recollection, neither C90 nor C99 even has the
> concept of directories.  

But your quote above says it's the ISO C function; is ISO C something
other than C90? 

> The horse's mouth, therefore, is POSIX, which says
>
> # The remove() function shall cause the file named by the pathname
> pointed to by path
> # to be no longer accessible by that name. A subsequent attempt to
> open that file using
> # that name shall fail, unless it is created anew.
>
> # If path does not name a directory, remove(path) shall be equivalent
> to unlink(path).
> # If path names a directory, remove(path) shall be equivalent to rmdir(path).
>
> The second paragraph is marked as an extension to C90.

Ok. I can understand that Win32, and therefore MinGW, is not POSIX
compliant.

> POSIX.2001, incidentally, is available online at
> http://www.opengroup.org/onlinepubs/009695399/nfindex.html (free
> registration required).  You have to read it carefully because not
> every system that we care about implements all of the 2001 spec, but
> it's a good starting point.

So mtn assumes unix = POSIX, win32 != POSIX? 

>> However, the actual difference between the code in win32 and unix
>> deals with what happens when the file to be removed does not exist.

Sigh. I don't know where my mind was. Here is the Win32 code:

  switch (get_path_status(path))
    {
    case path::directory:
      if (RemoveDirectoryA(path.c_str()))
        return;
      break;
    case path::file:
      if (DeleteFileA(path.c_str()))
        return;
      break;
    case path::nonexistent:
      // conveniently, GetLastError() will report the error code from
      // the GetFileAttributes() call in get_path_status() that told us
      // the path doesn't exist.
      break;
    }
  E(false, origin::system,
    F("could not remove '%s': %s") % path % os_strerror(GetLastError()));

which clearly handles directories, not just non-existent files. And it
throws an exception for non-existent files.

So the comment in platform.hh is not correct, but the directory must
be empty for do_remove to succeed. I'll fix it.

I'll try to make sure I've had enough sleep before I post again :(.

-- 
-- Stephe




reply via email to

[Prev in Thread] Current Thread [Next in Thread]