* 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:
parent
3323df7e0e
commit
40303ac9de
|
@ -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>
|
2007-02-27 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* fhandler.cc(fhandler_base::open): Open with READ_CONTROL only in
|
* fhandler.cc(fhandler_base::open): Open with READ_CONTROL only in
|
||||||
|
|
|
@ -4170,25 +4170,14 @@ get_user_proc_parms ()
|
||||||
return _upp;
|
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. */
|
/* Initialize cygcwd 'muto' for serializing access to cwd info. */
|
||||||
void
|
void
|
||||||
cwdstuff::init ()
|
cwdstuff::init ()
|
||||||
{
|
{
|
||||||
cwd_lock.init ("cwd_lock");
|
cwd_lock.init ("cwd_lock");
|
||||||
get_initial ();
|
get_initial ();
|
||||||
if (!dynamically_loaded)
|
/* Initially re-open the cwd to allow POSIX semantics. */
|
||||||
close_user_proc_parms_cwd_handle ();
|
set (win32, posix, true);
|
||||||
cwd_lock.release ();
|
cwd_lock.release ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4220,22 +4209,17 @@ cwdstuff::set (const char *win32_cwd, const char *posix_cwd, bool doit)
|
||||||
if (doit)
|
if (doit)
|
||||||
{
|
{
|
||||||
/* We utilize the user parameter block. The directory is
|
/* We utilize the user parameter block. The directory is
|
||||||
stored manually, but the handle to the directory is always
|
stored manually there. Why the hassle?
|
||||||
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.
|
|
||||||
|
|
||||||
- SetCurrentDirectory fails for directories with strict
|
- SetCurrentDirectory fails for directories with strict
|
||||||
permissions even for processes with the SE_BACKUP_NAME
|
permissions even for processes with the SE_BACKUP_NAME
|
||||||
privilege enabled. The reason is apparently that
|
privilege enabled. The reason is apparently that
|
||||||
SetCurrentDirectory calls NtOpenFile without the
|
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;
|
HANDLE h;
|
||||||
DWORD attr = GetFileAttributes (win32_cwd);
|
DWORD attr = GetFileAttributes (win32_cwd);
|
||||||
if (attr == INVALID_FILE_ATTRIBUTES)
|
if (attr == INVALID_FILE_ATTRIBUTES)
|
||||||
|
@ -4272,8 +4256,13 @@ cwdstuff::set (const char *win32_cwd, const char *posix_cwd, bool doit)
|
||||||
RtlOemStringToUnicodeString (
|
RtlOemStringToUnicodeString (
|
||||||
&get_user_proc_parms ()->CurrentDirectoryName,
|
&get_user_proc_parms ()->CurrentDirectoryName,
|
||||||
&as, FALSE);
|
&as, FALSE);
|
||||||
close_user_proc_parms_cwd_handle ();
|
PHANDLE phdl = &get_user_proc_parms ()->CurrentDirectoryHandle;
|
||||||
CloseHandle (h);
|
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 */
|
/* If there is no win32 path or it has the form c:xxx, get the value */
|
||||||
|
|
|
@ -1421,18 +1421,16 @@ rename (const char *oldpath, const char *newpath)
|
||||||
&& (len = strlen (real_old), strncasematch (real_old, real_new, len))
|
&& (len = strlen (real_old), strncasematch (real_old, real_new, len))
|
||||||
&& real_new[len] == '\\')
|
&& real_new[len] == '\\')
|
||||||
SetLastError (ERROR_INVALID_PARAMETER);
|
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 (),
|
else if (MoveFileEx (real_old.get_win32 (), real_new.get_win32 (),
|
||||||
MOVEFILE_REPLACE_EXISTING))
|
MOVEFILE_REPLACE_EXISTING))
|
||||||
res = 0;
|
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:
|
done:
|
||||||
if (res)
|
if (res)
|
||||||
|
@ -1462,7 +1460,7 @@ done:
|
||||||
if (lnk_suffix)
|
if (lnk_suffix)
|
||||||
{
|
{
|
||||||
*lnk_suffix = '.';
|
*lnk_suffix = '.';
|
||||||
DeleteFile (real_new);
|
unlink_nt (real_new, false);
|
||||||
}
|
}
|
||||||
/* Shortcut hack, No. 3, part 2 */
|
/* Shortcut hack, No. 3, part 2 */
|
||||||
/* If a file with the given name exists, it must be deleted after the
|
/* 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 = strrchr (real_new.get_win32 (), '.');
|
||||||
*lnk_suffix = '\0';
|
*lnk_suffix = '\0';
|
||||||
DeleteFile (real_new);
|
unlink_nt (real_new, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue