[Patch]: rmdir
Pierre A. Humblet
pierre@phumblet.no-ip.org
Thu Mar 18 03:23:00 GMT 2004
This is not a bug fix, just the reversion of a comment removal
following some recent tests on NT, plus some code simplification.
Here are the details:
- Until last Sunday, rmdir(".") didn't work.
- Now it works on 9x if the directory is empty.
"rmdir ." from a shell works there too.
- It also works on NT if the directory is empty AND no other process
is using it as working directory. "rmdir ." doesn't work from a shell.
Following my initial experience on 9x, I had deleted some comments.
That was premature.
2004-03-17 Pierre Humblet <pierre.humblet@ieee.org>
* dir.cc (rmdir): Reorganize error handling to reduce indentation.
-------------- next part --------------
Index: dir.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/dir.cc,v
retrieving revision 1.78
diff -u -p -r1.78 dir.cc
--- dir.cc 14 Mar 2004 16:16:45 -0000 1.78
+++ dir.cc 17 Mar 2004 02:10:24 -0000
@@ -328,6 +328,7 @@ rmdir (const char *dir)
for (bool is_cwd = false; ; is_cwd = true)
{
+ DWORD err;
int rc = RemoveDirectory (real_dir);
DWORD att = GetFileAttributes (real_dir);
@@ -338,48 +339,51 @@ rmdir (const char *dir)
/* RemoveDirectory on a samba drive doesn't return an error if the
directory can't be removed because it's not empty. Checking for
existence afterwards keeps us informed about success. */
- if (att != INVALID_FILE_ATTRIBUTES)
- set_errno (ENOTEMPTY);
- else
- res = 0;
- }
- else
- {
- /* This kludge detects if we are attempting to remove the current working
- directory. If so, we will move elsewhere to potentially allow the
- rmdir to succeed. This means that cygwin's concept of the current working
- directory != Windows concept but, hey, whaddaregonnado?
- FIXME: A potential workaround for this is for cygwin apps to *never* call
- SetCurrentDirectory. */
- if (strcasematch (real_dir, cygheap->cwd.win32)
- && !strcasematch ("c:\\", cygheap->cwd.win32) && !is_cwd)
- {
- DWORD err = GetLastError ();
- if (!SetCurrentDirectory ("c:\\"))
- SetLastError (err);
- else
- continue;
- }
- if (res)
+ if (att == INVALID_FILE_ATTRIBUTES)
{
- if (GetLastError () != ERROR_ACCESS_DENIED
- || !wincap.access_denied_on_delete ())
- __seterrno ();
- else
- set_errno (ENOTEMPTY); /* On 9X ERROR_ACCESS_DENIED is
- returned if you try to remove a
- non-empty directory. */
-
- /* If directory still exists, restore R/O attribute. */
- if (real_dir.has_attribute (FILE_ATTRIBUTE_READONLY))
- SetFileAttributes (real_dir, real_dir);
- if (is_cwd)
- SetCurrentDirectory (cygheap->cwd.win32);
+ res = 0;
+ break;
}
+ err = ERROR_DIR_NOT_EMPTY;
}
+ else
+ err = GetLastError ();
+
+ /* This kludge detects if we are attempting to remove the current working
+ directory. If so, we will move elsewhere to potentially allow the
+ rmdir to succeed. This means that cygwin's concept of the current working
+ directory != Windows concept but, hey, whaddaregonnado?
+ Note that this will not cause something like the following to work:
+ $ cd foo
+ $ rmdir .
+ since the shell will have foo "open" in the above case and so Windows will
+ not allow the deletion. (Actually it does on 9X.)
+ FIXME: A potential workaround for this is for cygwin apps to *never* call
+ SetCurrentDirectory. */
+
+ if (strcasematch (real_dir, cygheap->cwd.win32)
+ && !strcasematch ("c:\\", cygheap->cwd.win32)
+ && !is_cwd
+ && SetCurrentDirectory ("c:\\"))
+ continue;
+
+ /* On 9X ERROR_ACCESS_DENIED is returned
+ if you try to remove a non-empty directory. */
+ if (err == ERROR_ACCESS_DENIED
+ && wincap.access_denied_on_delete ())
+ err = ERROR_DIR_NOT_EMPTY;
+
+ __seterrno_from_win_error (err);
+
+ /* Directory still exists, restore its characteristics. */
+ if (real_dir.has_attribute (FILE_ATTRIBUTE_READONLY))
+ SetFileAttributes (real_dir, real_dir);
+ if (is_cwd)
+ SetCurrentDirectory (cygheap->cwd.win32);
break;
}
}
+
syscall_printf ("%d = rmdir (%s)", res, dir);
return res;
}
More information about the Cygwin-patches
mailing list