mingw_rmdir: set errno=ENOTEMPTY when appropriate
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Mon, 7 Feb 2011 20:54:01 +0000 (21:54 +0100)
committerJunio C Hamano <gitster@pobox.com>
Mon, 7 Feb 2011 23:45:54 +0000 (15:45 -0800)
On Windows, EACCES overrules ENOTEMPTY when calling rmdir(). But if the
directory is busy, we only want to retry deleting the directory if it
is empty, so test specifically for that case and set ENOTEMPTY rather
than EACCES.

Noticed by Greg Hazel.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
compat/mingw.c

index e55c3cac7747d4b381ff9943dd72314225f42c5c..878b1de97c6c437857e7a29e1b9afc677610f1fe 100644 (file)
@@ -225,6 +225,30 @@ int mingw_unlink(const char *pathname)
        return ret;
 }
 
+static int is_dir_empty(const char *path)
+{
+       struct strbuf buf = STRBUF_INIT;
+       WIN32_FIND_DATAA findbuf;
+       HANDLE handle;
+
+       strbuf_addf(&buf, "%s\\*", path);
+       handle = FindFirstFileA(buf.buf, &findbuf);
+       if (handle == INVALID_HANDLE_VALUE) {
+               strbuf_release(&buf);
+               return GetLastError() == ERROR_NO_MORE_FILES;
+       }
+
+       while (!strcmp(findbuf.cFileName, ".") ||
+                       !strcmp(findbuf.cFileName, ".."))
+               if (!FindNextFile(handle, &findbuf)) {
+                       strbuf_release(&buf);
+                       return GetLastError() == ERROR_NO_MORE_FILES;
+               }
+       FindClose(handle);
+       strbuf_release(&buf);
+       return 0;
+}
+
 #undef rmdir
 int mingw_rmdir(const char *pathname)
 {
@@ -233,6 +257,10 @@ int mingw_rmdir(const char *pathname)
        while ((ret = rmdir(pathname)) == -1 && tries < ARRAY_SIZE(delay)) {
                if (!is_file_in_use_error(GetLastError()))
                        break;
+               if (!is_dir_empty(pathname)) {
+                       errno = ENOTEMPTY;
+                       break;
+               }
                /*
                 * We assume that some other process had the source or
                 * destination file open at the wrong moment and retry.