OSDN Git Service

2004-03-14 Pierre Humblet <pierre.humblet@ieee.org>
authorphumblet <phumblet>
Sun, 14 Mar 2004 16:16:45 +0000 (16:16 +0000)
committerphumblet <phumblet>
Sun, 14 Mar 2004 16:16:45 +0000 (16:16 +0000)
        * dir.cc (rmdir): Construct real_dir with flag PC_FULL.
        Use a loop instead of recursion to handle the current directory.

winsup/cygwin/ChangeLog
winsup/cygwin/dir.cc

index 42bcc14..98a69c5 100644 (file)
@@ -1,3 +1,8 @@
+2004-03-14  Pierre Humblet <pierre.humblet@ieee.org>
+
+        * dir.cc (rmdir): Construct real_dir with flag PC_FULL.
+        Use a loop instead of recursion to handle the current directory.
+
 2004-03-14  Christopher Faylor  <cgf@redhat.com>
 
        * cygtls.cc (_cygtls::remove): Call remove_wq to ensure that wait stuff
@@ -94,7 +99,7 @@
        * sigproc.h (waitq): Delete declaration.
        * wait.cc (wait4): Use _my_tls waitq structure rather than per_thread.
 
-2004-02-11  Pierre Humblet  <pierre.humblet@ieee.org>
+2004-03-11  Pierre Humblet  <pierre.humblet@ieee.org>
 
        * cygtls.h (_cygtls::newmask): Delete member.
        (_cygtls::deltamask): New member.
index 90ca1ca..2fccabc 100644 (file)
@@ -308,7 +308,7 @@ rmdir (const char *dir)
   int res = -1;
   DWORD devn;
 
-  path_conv real_dir (dir, PC_SYM_NOFOLLOW);
+  path_conv real_dir (dir, PC_SYM_NOFOLLOW | PC_FULL);
 
   if (real_dir.error)
     set_errno (real_dir.error);
@@ -326,60 +326,60 @@ rmdir (const char *dir)
        SetFileAttributes (real_dir,
                           (DWORD) real_dir & ~FILE_ATTRIBUTE_READONLY);
 
-      int rc = RemoveDirectory (real_dir);
-      DWORD att = GetFileAttributes (real_dir);
+      for (bool is_cwd = false; ; is_cwd = true)
+        {
+         int rc = RemoveDirectory (real_dir);
+         DWORD att = GetFileAttributes (real_dir);
 
-      /* Sometimes smb indicates failure when it really succeeds, so check for
-        this case specifically. */
-      if (rc || att == INVALID_FILE_ATTRIBUTES)
-       {
-         /* 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?
-            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.
-            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))
+         /* Sometimes smb indicates failure when it really succeeds, so check for
+            this case specifically. */
+         if (rc || att == INVALID_FILE_ATTRIBUTES)
            {
-             DWORD err = GetLastError ();
-             if (!SetCurrentDirectory ("c:\\"))
-               SetLastError (err);
-             else if ((res = rmdir (dir)))
-               SetCurrentDirectory (cygheap->cwd.win32);
+             /* 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;
            }
-         if (res)
+         else
            {
-             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);
+             /* 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 (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);
+               }
            }
+         break;
        }
     }
-
   syscall_printf ("%d = rmdir (%s)", res, dir);
   return res;
 }