mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-01-31 11:30:56 +08:00
* fhandler_disk_file.cc (fhandler_disk_file::rmdir): Implement rmdir
on NT by calling unlink_nt. Check for directory here. * syscalls.cc (try_to_bin): Fix buggy debug_printf statement. (unlink_nt): Make non-static. Don't use delete-on-close semantics on directoires. Explain why.
This commit is contained in:
parent
2731a97413
commit
3be6ababd8
@ -1,3 +1,11 @@
|
|||||||
|
2007-01-26 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* fhandler_disk_file.cc (fhandler_disk_file::rmdir): Implement rmdir
|
||||||
|
on NT by calling unlink_nt. Check for directory here.
|
||||||
|
* syscalls.cc (try_to_bin): Fix buggy debug_printf statement.
|
||||||
|
(unlink_nt): Make non-static. Don't use delete-on-close semantics on
|
||||||
|
directoires. Explain why.
|
||||||
|
|
||||||
2007-01-24 Corinna Vinschen <corinna@vinschen.de>
|
2007-01-24 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* net.cc (if_nametoindex): This time, really free IP_ADAPTER_ADDRESSES
|
* net.cc (if_nametoindex): This time, really free IP_ADAPTER_ADDRESSES
|
||||||
|
@ -1447,15 +1447,31 @@ fhandler_disk_file::mkdir (mode_t mode)
|
|||||||
int
|
int
|
||||||
fhandler_disk_file::rmdir ()
|
fhandler_disk_file::rmdir ()
|
||||||
{
|
{
|
||||||
|
extern DWORD unlink_nt (path_conv &win32_name, bool setattrs);
|
||||||
|
|
||||||
int res = -1;
|
int res = -1;
|
||||||
|
|
||||||
|
if (!pc.isdir ())
|
||||||
|
{
|
||||||
|
set_errno (ENOTDIR);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
/* Even own directories can't be removed if R/O attribute is set. */
|
/* Even own directories can't be removed if R/O attribute is set. */
|
||||||
if (pc.has_attribute (FILE_ATTRIBUTE_READONLY))
|
if (pc.has_attribute (FILE_ATTRIBUTE_READONLY))
|
||||||
SetFileAttributes (get_win32_name (),
|
SetFileAttributes (get_win32_name (),
|
||||||
(DWORD) pc & ~FILE_ATTRIBUTE_READONLY);
|
(DWORD) pc & ~FILE_ATTRIBUTE_READONLY);
|
||||||
|
|
||||||
DWORD err, att = 0;
|
DWORD err, att = 0;
|
||||||
int rc = RemoveDirectory (get_win32_name ());
|
int rc;
|
||||||
|
|
||||||
|
if (wincap.is_winnt ())
|
||||||
|
{
|
||||||
|
rc = !(err = unlink_nt (pc, pc.has_attribute (FILE_ATTRIBUTE_READONLY)));
|
||||||
|
if (err)
|
||||||
|
SetLastError (err);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rc = RemoveDirectory (get_win32_name ());
|
||||||
|
|
||||||
if (isremote () && exists ())
|
if (isremote () && exists ())
|
||||||
att = GetFileAttributes (get_win32_name ());
|
att = GetFileAttributes (get_win32_name ());
|
||||||
@ -1488,7 +1504,7 @@ fhandler_disk_file::rmdir ()
|
|||||||
__seterrno_from_win_error (err);
|
__seterrno_from_win_error (err);
|
||||||
|
|
||||||
/* Directory still exists, restore its characteristics. */
|
/* Directory still exists, restore its characteristics. */
|
||||||
if (pc.has_attribute (FILE_ATTRIBUTE_READONLY))
|
if (!wincap.is_winnt () && pc.has_attribute (FILE_ATTRIBUTE_READONLY))
|
||||||
SetFileAttributes (get_win32_name (), (DWORD) pc);
|
SetFileAttributes (get_win32_name (), (DWORD) pc);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
@ -225,7 +225,8 @@ try_to_bin (path_conv &win32_path, HANDLE h)
|
|||||||
pfri->FileNameLength = uname.Length;
|
pfri->FileNameLength = uname.Length;
|
||||||
status = NtSetInformationFile (h, &io, pfri, size, FileRenameInformation);
|
status = NtSetInformationFile (h, &io, pfri, size, FileRenameInformation);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
debug_printf ("Move %s to %s failed, status = %p", status);
|
debug_printf ("Move %s to %s failed, status = %p", win32_path.get_win32 (),
|
||||||
|
recycler, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD
|
static DWORD
|
||||||
@ -236,7 +237,7 @@ unlink_9x (path_conv &win32_name)
|
|||||||
return GetLastError ();
|
return GetLastError ();
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD
|
DWORD
|
||||||
unlink_nt (path_conv &win32_name, bool setattrs)
|
unlink_nt (path_conv &win32_name, bool setattrs)
|
||||||
{
|
{
|
||||||
WCHAR wpath[CYG_MAX_PATH + 10];
|
WCHAR wpath[CYG_MAX_PATH + 10];
|
||||||
@ -247,19 +248,24 @@ unlink_nt (path_conv &win32_name, bool setattrs)
|
|||||||
HANDLE h;
|
HANDLE h;
|
||||||
|
|
||||||
ULONG flags = FILE_OPEN_FOR_BACKUP_INTENT;
|
ULONG flags = FILE_OPEN_FOR_BACKUP_INTENT;
|
||||||
/* Don't try "delete on close" if the file is on a remote share. If two
|
/* Don't open directories with "delete on close", because the NT internal
|
||||||
processes have open handles on a file and one of them calls unlink,
|
semantic is apparently different from the file semantic. If a directory
|
||||||
then it happens that the file is remove from the remote share even
|
is opened "delete on close", the rename operation in try_to_bin fails
|
||||||
though the other process still has an open handle. This other process
|
with STATUS_ACCESS_DENIED. So directories must be deleted using
|
||||||
than gets Win32 error 59, ERROR_UNEXP_NET_ERR when trying to access the
|
NtSetInformationFile, class FileDispositionInformation, which works fine.
|
||||||
file.
|
|
||||||
That does not happen when using DeleteFile (NtSetInformationFile, class
|
Don't try "delete on close" if the file is on a remote share. If two
|
||||||
FileDispositionInformation), which nicely succeeds but still, the file
|
processes have open handles on a file and one of them calls unlink, then
|
||||||
is available for the other process.
|
it happens that the file is removed from the remote share even though the
|
||||||
Microsoft KB 837665 describes this problem as a bug in 2K3, but I have
|
other process still has an open handle. This other process than gets
|
||||||
reproduced it on shares on Samba 2.2.8, Samba 3.0.2, NT4SP6, XP64SP1 and
|
Win32 error 59, ERROR_UNEXP_NET_ERR when trying to access the file. That
|
||||||
2K3 and in all cases, DeleteFile works, "delete on close" does not. */
|
does not happen when using NtSetInformationFile, class
|
||||||
if (!win32_name.isremote ())
|
FileDispositionInformation, which nicely succeeds but still, the file is
|
||||||
|
available for the other process. Microsoft KB 837665 describes this
|
||||||
|
problem as a bug in 2K3, but I have reproduced it on shares on Samba
|
||||||
|
2.2.8, Samba 3.0.2, NT4SP6, XP64SP1 and 2K3 and in all cases, DeleteFile
|
||||||
|
works, "delete on close" does not. */
|
||||||
|
if (!win32_name.isdir () && !win32_name.isremote ())
|
||||||
flags |= FILE_DELETE_ON_CLOSE;
|
flags |= FILE_DELETE_ON_CLOSE;
|
||||||
/* Add the reparse point flag to native symlinks, otherwise we remove the
|
/* Add the reparse point flag to native symlinks, otherwise we remove the
|
||||||
target, not the symlink. */
|
target, not the symlink. */
|
||||||
@ -301,7 +307,7 @@ unlink_nt (path_conv &win32_name, bool setattrs)
|
|||||||
|
|
||||||
DWORD lasterr = 0;
|
DWORD lasterr = 0;
|
||||||
|
|
||||||
if (win32_name.isremote ())
|
if (win32_name.isdir () || win32_name.isremote ())
|
||||||
{
|
{
|
||||||
FILE_DISPOSITION_INFORMATION disp = { TRUE };
|
FILE_DISPOSITION_INFORMATION disp = { TRUE };
|
||||||
status = NtSetInformationFile (h, &io, &disp, sizeof disp,
|
status = NtSetInformationFile (h, &io, &disp, sizeof disp,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user