Eric Blake <e...@byu.net> 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