diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2007-02-27 18:38:22 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2007-02-27 18:38:22 +0000 |
commit | 40303ac9de08f2a78cde0ffc04622f26df58a719 (patch) | |
tree | 7d8fafb3e6ea1de47bd8336602e064ea1bf4e8d1 /winsup | |
parent | 3323df7e0ed8be20dcd1643212858399514dd158 (diff) | |
download | newlib-40303ac9de08f2a78cde0ffc04622f26df58a719.zip newlib-40303ac9de08f2a78cde0ffc04622f26df58a719.tar.gz newlib-40303ac9de08f2a78cde0ffc04622f26df58a719.tar.bz2 |
* path.cc (close_user_proc_parms_cwd_handle): Remove.
(cwdstuff::init): Don't call close_user_proc_parms_cwd_handle.
Call set to set cwd with all-sharing handle.
(cwdstuff::set): Fix comment. Don't close cwd handle. Set in
user parameter block instead and close old cwd handle.
* syscalls.cc (rename): Call unlink_nt instead of RemoveDirectory or
DeleteFile to allow deleting shared files/directories.
Diffstat (limited to 'winsup')
-rw-r--r-- | winsup/cygwin/ChangeLog | 10 | ||||
-rw-r--r-- | winsup/cygwin/path.cc | 43 | ||||
-rw-r--r-- | winsup/cygwin/syscalls.cc | 20 |
3 files changed, 35 insertions, 38 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 1dc89f7..e99409e 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,5 +1,15 @@ 2007-02-27 Corinna Vinschen <corinna@vinschen.de> + * path.cc (close_user_proc_parms_cwd_handle): Remove. + (cwdstuff::init): Don't call close_user_proc_parms_cwd_handle. + Call set to set cwd with all-sharing handle. + (cwdstuff::set): Fix comment. Don't close cwd handle. Set in + user parameter block instead and close old cwd handle. + * syscalls.cc (rename): Call unlink_nt instead of RemoveDirectory or + DeleteFile to allow deleting shared files/directories. + +2007-02-27 Corinna Vinschen <corinna@vinschen.de> + * fhandler.cc(fhandler_base::open): Open with READ_CONTROL only in case of query_open flag set to query_read_control. Add case for new query_read_attributes flag. diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index c0ad9a8..a29eaa7 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -4170,25 +4170,14 @@ get_user_proc_parms () return _upp; } -static void -close_user_proc_parms_cwd_handle () -{ - PHANDLE phdl = &get_user_proc_parms ()->CurrentDirectoryHandle; - if (*phdl) - { - NtClose (*phdl); - *phdl = NULL; - } -} - /* Initialize cygcwd 'muto' for serializing access to cwd info. */ void cwdstuff::init () { cwd_lock.init ("cwd_lock"); get_initial (); - if (!dynamically_loaded) - close_user_proc_parms_cwd_handle (); + /* Initially re-open the cwd to allow POSIX semantics. */ + set (win32, posix, true); cwd_lock.release (); } @@ -4220,22 +4209,17 @@ cwdstuff::set (const char *win32_cwd, const char *posix_cwd, bool doit) if (doit) { /* We utilize the user parameter block. The directory is - stored manually, but the handle to the directory is always - closed and set to NULL. This way the directory isn't blocked - even if it's the cwd of a Cygwin process. - - Why the hassle? - - - A process has always an open handle to the current working - directory which disallows manipulating this directory. - POSIX allows to remove a directory if the permissions are ok. - The fact that its the cwd of some process doesn't matter. - + stored manually there. Why the hassle? + - SetCurrentDirectory fails for directories with strict permissions even for processes with the SE_BACKUP_NAME privilege enabled. The reason is apparently that SetCurrentDirectory calls NtOpenFile without the - FILE_OPEN_FOR_BACKUP_INTENT flag set. */ + FILE_OPEN_FOR_BACKUP_INTENT flag set. + + - Unlinking a cwd fails because SetCurrentDirectory seems to + open directories so that deleting the directory is disallowed. + The below code opens with *all* sharing flags set. */ HANDLE h; DWORD attr = GetFileAttributes (win32_cwd); if (attr == INVALID_FILE_ATTRIBUTES) @@ -4272,8 +4256,13 @@ cwdstuff::set (const char *win32_cwd, const char *posix_cwd, bool doit) RtlOemStringToUnicodeString ( &get_user_proc_parms ()->CurrentDirectoryName, &as, FALSE); - close_user_proc_parms_cwd_handle (); - CloseHandle (h); + PHANDLE phdl = &get_user_proc_parms ()->CurrentDirectoryHandle; + if (*phdl) + { + HANDLE old_h = *phdl; + *phdl = h; + CloseHandle (old_h); + } } } /* If there is no win32 path or it has the form c:xxx, get the value */ diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 976e660..30a67b8 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -1421,18 +1421,16 @@ rename (const char *oldpath, const char *newpath) && (len = strlen (real_old), strncasematch (real_old, real_new, len)) && real_new[len] == '\\') SetLastError (ERROR_INVALID_PARAMETER); - else if (real_new.isdir ()) - { - /* Since neither MoveFileEx(MOVEFILE_REPLACE_EXISTING) nor DeleteFile - allow to remove directories, this case is handled separately. */ - if (!RemoveDirectoryA (real_new)) - syscall_printf ("Can't remove target directory"); - else if (MoveFile (real_old, real_new)) - res = 0; - } else if (MoveFileEx (real_old.get_win32 (), real_new.get_win32 (), MOVEFILE_REPLACE_EXISTING)) res = 0; + else if ((lasterr = unlink_nt (real_new, false))) + { + SetLastError (lasterr); + syscall_printf ("Can't remove target file/dir, %E"); + } + else if (MoveFile (real_old, real_new)) + res = 0; done: if (res) @@ -1462,7 +1460,7 @@ done: if (lnk_suffix) { *lnk_suffix = '.'; - DeleteFile (real_new); + unlink_nt (real_new, false); } /* Shortcut hack, No. 3, part 2 */ /* If a file with the given name exists, it must be deleted after the @@ -1474,7 +1472,7 @@ done: { lnk_suffix = strrchr (real_new.get_win32 (), '.'); *lnk_suffix = '\0'; - DeleteFile (real_new); + unlink_nt (real_new, false); } } |