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>
* 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.

View 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);
}
if (res)
{
if (GetLastError () != ERROR_ACCESS_DENIED
|| !wincap.access_denied_on_delete ())
__seterrno ();
/* 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
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);
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 (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;
}