* 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>
|
||||
|
||||
* fhandler.cc(fhandler_base::open): Open with READ_CONTROL only in
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue