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.
This commit is contained in:
Pierre Humblet 2004-03-14 16:16:45 +00:00
parent f8a8e7a1f6
commit 83a74ea24a
2 changed files with 55 additions and 50 deletions

View 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> 2004-03-14 Christopher Faylor <cgf@redhat.com>
* cygtls.cc (_cygtls::remove): Call remove_wq to ensure that wait stuff * cygtls.cc (_cygtls::remove): Call remove_wq to ensure that wait stuff
@ -94,7 +99,7 @@
* sigproc.h (waitq): Delete declaration. * sigproc.h (waitq): Delete declaration.
* wait.cc (wait4): Use _my_tls waitq structure rather than per_thread. * 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.h (_cygtls::newmask): Delete member.
(_cygtls::deltamask): New member. (_cygtls::deltamask): New member.

View File

@ -308,7 +308,7 @@ rmdir (const char *dir)
int res = -1; int res = -1;
DWORD devn; DWORD devn;
path_conv real_dir (dir, PC_SYM_NOFOLLOW); path_conv real_dir (dir, PC_SYM_NOFOLLOW | PC_FULL);
if (real_dir.error) if (real_dir.error)
set_errno (real_dir.error); set_errno (real_dir.error);
@ -326,60 +326,60 @@ rmdir (const char *dir)
SetFileAttributes (real_dir, SetFileAttributes (real_dir,
(DWORD) real_dir & ~FILE_ATTRIBUTE_READONLY); (DWORD) real_dir & ~FILE_ATTRIBUTE_READONLY);
int rc = RemoveDirectory (real_dir); for (bool is_cwd = false; ; is_cwd = true)
DWORD att = GetFileAttributes (real_dir); {
int rc = RemoveDirectory (real_dir);
DWORD att = GetFileAttributes (real_dir);
/* Sometimes smb indicates failure when it really succeeds, so check for /* Sometimes smb indicates failure when it really succeeds, so check for
this case specifically. */ this case specifically. */
if (rc || att == INVALID_FILE_ATTRIBUTES) 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))
{ {
DWORD err = GetLastError (); /* RemoveDirectory on a samba drive doesn't return an error if the
if (!SetCurrentDirectory ("c:\\")) directory can't be removed because it's not empty. Checking for
SetLastError (err); existence afterwards keeps us informed about success. */
else if ((res = rmdir (dir))) if (att != INVALID_FILE_ATTRIBUTES)
SetCurrentDirectory (cygheap->cwd.win32); set_errno (ENOTEMPTY);
}
if (res)
{
if (GetLastError () != ERROR_ACCESS_DENIED
|| !wincap.access_denied_on_delete ())
__seterrno ();
else else
set_errno (ENOTEMPTY); /* On 9X ERROR_ACCESS_DENIED is res = 0;
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);
} }
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 (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); syscall_printf ("%d = rmdir (%s)", res, dir);
return res; return res;
} }