[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