* syscalls.cc (rename): Drop handling paths > 32757 chars, emit EINVAL
instead, thus simplifying code allocating and filling pfri. Drop size and use constant expression in NtSetInformationFile call. Add comments. Drop redundant test for fs_serial_number and change comment accordingly.
This commit is contained in:
parent
2880becf0c
commit
7142197465
|
@ -1,3 +1,10 @@
|
||||||
|
2013-01-11 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* syscalls.cc (rename): Drop handling paths > 32757 chars, emit EINVAL
|
||||||
|
instead, thus simplifying code allocating and filling pfri. Drop size
|
||||||
|
and use constant expression in NtSetInformationFile call. Add comments.
|
||||||
|
Drop redundant test for fs_serial_number and change comment accordingly.
|
||||||
|
|
||||||
2013-01-11 Thomas Wolff <towo@towo.net>
|
2013-01-11 Thomas Wolff <towo@towo.net>
|
||||||
|
|
||||||
* fhandler.h (class dev_console): Flag for expanded control sequence.
|
* fhandler.h (class dev_console): Flag for expanded control sequence.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* syscalls.cc: syscalls
|
/* syscalls.cc: syscalls
|
||||||
|
|
||||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||||
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc.
|
2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
@ -2035,7 +2035,6 @@ rename (const char *oldpath, const char *newpath)
|
||||||
HANDLE old_trans = NULL, trans = NULL;
|
HANDLE old_trans = NULL, trans = NULL;
|
||||||
OBJECT_ATTRIBUTES attr;
|
OBJECT_ATTRIBUTES attr;
|
||||||
IO_STATUS_BLOCK io;
|
IO_STATUS_BLOCK io;
|
||||||
ULONG size;
|
|
||||||
FILE_STANDARD_INFORMATION ofsi;
|
FILE_STANDARD_INFORMATION ofsi;
|
||||||
PFILE_RENAME_INFORMATION pfri;
|
PFILE_RENAME_INFORMATION pfri;
|
||||||
|
|
||||||
|
@ -2407,14 +2406,13 @@ retry:
|
||||||
/* SUSv3: If the old argument and the new argument resolve to the same
|
/* SUSv3: If the old argument and the new argument resolve to the same
|
||||||
existing file, rename() shall return successfully and perform no
|
existing file, rename() shall return successfully and perform no
|
||||||
other action.
|
other action.
|
||||||
The test tries to be as quick as possible. First it tests for identical
|
The test tries to be as quick as possible. Due to the above cross device
|
||||||
volume serial numbers because that information is available anyway.
|
check we already know both files are on the same device. So it just
|
||||||
Then it tests if oldpath has more than 1 hardlink, then it opens newpath
|
tests if oldpath has more than 1 hardlink, then it opens newpath
|
||||||
and tests for identical file ids. If so, oldpath and newpath refer to
|
and tests for identical file ids. If so, oldpath and newpath refer to
|
||||||
the same file. */
|
the same file. */
|
||||||
if ((removepc || dstpc->exists ())
|
if ((removepc || dstpc->exists ())
|
||||||
&& !oldpc.isdir ()
|
&& !oldpc.isdir ()
|
||||||
&& dstpc->fs_serial_number () == oldpc.fs_serial_number ()
|
|
||||||
&& NT_SUCCESS (NtQueryInformationFile (fh, &io, &ofsi, sizeof ofsi,
|
&& NT_SUCCESS (NtQueryInformationFile (fh, &io, &ofsi, sizeof ofsi,
|
||||||
FileStandardInformation))
|
FileStandardInformation))
|
||||||
&& ofsi.NumberOfLinks > 1
|
&& ofsi.NumberOfLinks > 1
|
||||||
|
@ -2440,6 +2438,18 @@ retry:
|
||||||
}
|
}
|
||||||
NtClose (nfh);
|
NtClose (nfh);
|
||||||
}
|
}
|
||||||
|
/* Create FILE_RENAME_INFORMATION struct. Using a tmp_pathbuf area allows
|
||||||
|
for paths of up to 32757 chars. This test is just for paranoia's sake. */
|
||||||
|
if (dstpc->get_nt_native_path ()->Length > NT_MAX_PATH * sizeof (WCHAR)
|
||||||
|
- sizeof (FILE_RENAME_INFORMATION))
|
||||||
|
{
|
||||||
|
debug_printf ("target filename too long");
|
||||||
|
set_errno (EINVAL);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
pfri = (PFILE_RENAME_INFORMATION) tp.w_get ();
|
||||||
|
pfri->ReplaceIfExists = TRUE;
|
||||||
|
pfri->RootDirectory = NULL;
|
||||||
if (oldpc.fs_is_nfs ())
|
if (oldpc.fs_is_nfs ())
|
||||||
{
|
{
|
||||||
/* Workaround depressing NFS bug. FILE_RENAME_INFORMATION.FileName
|
/* Workaround depressing NFS bug. FILE_RENAME_INFORMATION.FileName
|
||||||
|
@ -2477,30 +2487,18 @@ retry:
|
||||||
while ((oldp = wcschr (++oldp, L'\\')) != NULL)
|
while ((oldp = wcschr (++oldp, L'\\')) != NULL)
|
||||||
newp = wcpcpy (newp, L"..\\");
|
newp = wcpcpy (newp, L"..\\");
|
||||||
newp = wcpcpy (newp, dstp);
|
newp = wcpcpy (newp, dstp);
|
||||||
size = sizeof (FILE_RENAME_INFORMATION)
|
|
||||||
+ (newp - newdst) * sizeof (WCHAR);
|
|
||||||
if (size > NT_MAX_PATH * sizeof (WCHAR)) /* Hopefully very seldom. */
|
|
||||||
pfri = (PFILE_RENAME_INFORMATION) alloca (size);
|
|
||||||
else
|
|
||||||
pfri = (PFILE_RENAME_INFORMATION) tp.w_get ();
|
|
||||||
pfri->FileNameLength = (newp - newdst) * sizeof (WCHAR);
|
pfri->FileNameLength = (newp - newdst) * sizeof (WCHAR);
|
||||||
memcpy (&pfri->FileName, newdst, pfri->FileNameLength);
|
memcpy (&pfri->FileName, newdst, pfri->FileNameLength);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size = sizeof (FILE_RENAME_INFORMATION)
|
|
||||||
+ dstpc->get_nt_native_path ()->Length;
|
|
||||||
if (size > NT_MAX_PATH * sizeof (WCHAR)) /* Hopefully very seldom. */
|
|
||||||
pfri = (PFILE_RENAME_INFORMATION) alloca (size);
|
|
||||||
else
|
|
||||||
pfri = (PFILE_RENAME_INFORMATION) tp.w_get ();
|
|
||||||
pfri->FileNameLength = dstpc->get_nt_native_path ()->Length;
|
pfri->FileNameLength = dstpc->get_nt_native_path ()->Length;
|
||||||
memcpy (&pfri->FileName, dstpc->get_nt_native_path ()->Buffer,
|
memcpy (&pfri->FileName, dstpc->get_nt_native_path ()->Buffer,
|
||||||
pfri->FileNameLength);
|
pfri->FileNameLength);
|
||||||
}
|
}
|
||||||
pfri->ReplaceIfExists = TRUE;
|
status = NtSetInformationFile (fh, &io, pfri,
|
||||||
pfri->RootDirectory = NULL;
|
sizeof *pfri + pfri->FileNameLength,
|
||||||
status = NtSetInformationFile (fh, &io, pfri, size, FileRenameInformation);
|
FileRenameInformation);
|
||||||
/* This happens if the access rights don't allow deleting the destination.
|
/* This happens if the access rights don't allow deleting the destination.
|
||||||
Even if the handle to the original file is opened with BACKUP
|
Even if the handle to the original file is opened with BACKUP
|
||||||
and/or RECOVERY, these flags don't apply to the destination of the
|
and/or RECOVERY, these flags don't apply to the destination of the
|
||||||
|
@ -2537,7 +2535,8 @@ retry:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (NT_SUCCESS (status = unlink_nt (*dstpc)))
|
if (NT_SUCCESS (status = unlink_nt (*dstpc)))
|
||||||
status = NtSetInformationFile (fh, &io, pfri, size,
|
status = NtSetInformationFile (fh, &io, pfri,
|
||||||
|
sizeof *pfri + pfri->FileNameLength,
|
||||||
FileRenameInformation);
|
FileRenameInformation);
|
||||||
}
|
}
|
||||||
if (NT_SUCCESS (status))
|
if (NT_SUCCESS (status))
|
||||||
|
|
Loading…
Reference in New Issue