bug-gnulib
[Top][All Lists]
Advanced

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

Re: mingw remove bug


From: Ben Pfaff
Subject: Re: mingw remove bug
Date: Mon, 14 Sep 2009 19:42:02 -0700
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux)

Eric Blake <address@hidden> writes:

> According to Ben Pfaff on 9/14/2009 5:51 PM:
>>> +  /* Mingw remove("file/") fails with EINVAL, instead of the required
>>> +     ENOTDIR.  */
>>> +  if (ISSLASH (name[len - 1]))
>>> +    {
>>> +      errno = ENOTDIR;
>>> +      return -1;
>>> +    }
>> 
>> I believe that this will return ENOTDIR for a file whose name
>> ends in '/' or '\' and on which lstat() fails (e.g. for a file
>> that doesn't exist).
>
> I tested; it failed with EINVAL on mingw.  And on Solaris 8,
> unlink("file/") succeeds at removing file; I need to test whether
> remove("file/") succeeds as well, or else enhance remove.m4 to work around
> that bug too.

I think maybe I didn't communicate well.  On GNU/Linux, this
program outputs "remove: No such file or directory" when passed
"nonexistent/" as its argument

    #include <stdio.h>
    #include <string.h>

    int
    main (int argc, char *argv[])
    {
      if (remove (argv[1]))
        perror ("remove");
      return 0;
    }

But with the same argument this program outputs "remove: Not a
directory":

    #include <errno.h>
    #include <stdio.h>
    #include <string.h>
    #include <sys/stat.h>
    #include <unistd.h>

    #define ISSLASH(C) ((C) == '/')

    static int
    rpl_remove (char const *name)
    {
      /* Mingw remove() fails with EPERM on empty directories.  */
      struct stat st;
      size_t len = strlen (name);
      if (!len)
        {
          errno = ENOENT;
          return -1;
        }

      if (lstat (name, &st) == 0 && S_ISDIR (st.st_mode))
        {
          /* Mingw rmdir("empty/.") mistakenly succeeds.  */
          while (ISSLASH (name[len - 1]))
            len--;
          if (name[len - 1] == '.' && (1 == len || ISSLASH (name[len - 2])))
            {
              errno = EINVAL;
              return -1;
            }
          return rmdir (name);
        }
      /* Mingw remove("file/") fails with EINVAL, instead of the required
         ENOTDIR.  */
      if (ISSLASH (name[len - 1]))
        {
          errno = ENOTDIR;
          return -1;
        }
      return remove (name);
    }

    int
    main (int argc, char *argv[])
    {
      if (rpl_remove (argv[1]))
        perror ("remove");
      return 0;
    }

I'm arguing that the second program should also report "No such
file or directory".
-- 
"Term, holidays, term, holidays, till we leave school,
 and then work, work, work till we die."
C. S. Lewis





reply via email to

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