* 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.
This commit is contained in:
Corinna Vinschen 2007-02-27 18:38:22 +00:00
parent 3323df7e0e
commit 40303ac9de
3 changed files with 35 additions and 38 deletions

View File

@ -1,3 +1,13 @@
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

View File

@ -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 */

View File

@ -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);
}
}