From 8eca5362726ea2c0a83ca1e9d64086f2e58c22f5 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 30 Nov 2006 10:17:24 +0000 Subject: * dir.cc (mkdir): Check last path component for "..". (rmdir): Don't check last path component for "..". * fhandler_disk_file.cc (fhandler_disk_file::rmdir): Drop kludge which tries to allow deleting the current working directory. * path.cc (has_dot_last_component): Add parameter to indicate testing for "..". Take trailing slash into account. (symlink_info::posixify): Rely on cygheap->cwd.win32 having a useful value. (cwdstuff::init): Initialize cygheap->cwd with current working directory. Change to windows_system_directory afterwards. (cwdstuff::set): Never call SetCurrentDirectory here. Just check if changing into target directory would be allowed. Add comment to explain why. * path.h (has_dot_last_component): Declare with second parameter. * pinfo.cc (pinfo::zap_cwd): Remove. (pinfo::exit): Drop call to zap_cwd. * pinfo.h (class pinfo): Remove declaration of zap_cwd. * spawn.cc (spawn_guts): Set current working directory for non-Cygwin child applications. Drop call to zap_cwd. --- winsup/cygwin/fhandler_disk_file.cc | 94 +++++++++++++------------------------ 1 file changed, 33 insertions(+), 61 deletions(-) (limited to 'winsup/cygwin/fhandler_disk_file.cc') diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index f3b5ec03e..2d6ae3578 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -1449,70 +1449,42 @@ fhandler_disk_file::rmdir () SetFileAttributes (get_win32_name (), (DWORD) pc & ~FILE_ATTRIBUTE_READONLY); - for (bool is_cwd = false; ; is_cwd = true) - { - DWORD err, att = 0; - int rc = RemoveDirectory (get_win32_name ()); + DWORD err, att = 0; + int rc = RemoveDirectory (get_win32_name ()); - if (isremote () && exists ()) - att = GetFileAttributes (get_win32_name ()); + if (isremote () && exists ()) + att = GetFileAttributes (get_win32_name ()); - /* 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 (!isremote () || att == INVALID_FILE_ATTRIBUTES) - { - 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. */ - - extern char windows_system_directory[]; - if (strcasematch (get_win32_name (), cygheap->cwd.win32) - && !strcasematch (windows_system_directory, cygheap->cwd.win32) - && !is_cwd - && SetCurrentDirectory (windows_system_directory)) - 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; - /* ...and, that's *not* funny, when trying to remove a non-existing - directory on a share, which is hosted by a 9x machine, the error - code ERROR_INVALID_FUNCTION is returned. */ - else if (err == ERROR_INVALID_FUNCTION) - err = ERROR_FILE_NOT_FOUND; - - __seterrno_from_win_error (err); - - /* Directory still exists, restore its characteristics. */ - if (pc.has_attribute (FILE_ATTRIBUTE_READONLY)) - SetFileAttributes (get_win32_name (), (DWORD) pc); - if (is_cwd) - SetCurrentDirectory (get_win32_name ()); - break; + /* 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 (!isremote () || att == INVALID_FILE_ATTRIBUTES) + return res; + + err = ERROR_DIR_NOT_EMPTY; } + else + err = GetLastError (); + /* 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; + /* ...and, that's *not* funny, when trying to remove a non-existing + directory on a share, which is hosted by a 9x machine, the error + code ERROR_INVALID_FUNCTION is returned. */ + else if (err == ERROR_INVALID_FUNCTION) + err = ERROR_FILE_NOT_FOUND; + + __seterrno_from_win_error (err); + + /* Directory still exists, restore its characteristics. */ + if (pc.has_attribute (FILE_ATTRIBUTE_READONLY)) + SetFileAttributes (get_win32_name (), (DWORD) pc); return res; } -- cgit v1.2.3