Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2013-01-11 16:34:41 +0400
committerCorinna Vinschen <corinna@vinschen.de>2013-01-11 16:34:41 +0400
commit7142197465d10f4284519c6463b52ed3451089f1 (patch)
tree810c6ffd6ec2ac83dd7bf5ba00e7e1e531f66d68
parent2880becf0c27375885f1b7d9fd4444065a67462e (diff)
* 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.
-rw-r--r--winsup/cygwin/ChangeLog7
-rw-r--r--winsup/cygwin/syscalls.cc43
2 files changed, 28 insertions, 22 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 7f40ffe6d..32d87e080 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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>
* fhandler.h (class dev_console): Flag for expanded control sequence.
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 1aedc1f61..a23611e36 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -1,7 +1,7 @@
/* syscalls.cc: syscalls
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.
@@ -2035,7 +2035,6 @@ rename (const char *oldpath, const char *newpath)
HANDLE old_trans = NULL, trans = NULL;
OBJECT_ATTRIBUTES attr;
IO_STATUS_BLOCK io;
- ULONG size;
FILE_STANDARD_INFORMATION ofsi;
PFILE_RENAME_INFORMATION pfri;
@@ -2407,14 +2406,13 @@ retry:
/* SUSv3: If the old argument and the new argument resolve to the same
existing file, rename() shall return successfully and perform no
other action.
- The test tries to be as quick as possible. First it tests for identical
- volume serial numbers because that information is available anyway.
- Then it tests if oldpath has more than 1 hardlink, then it opens newpath
+ The test tries to be as quick as possible. Due to the above cross device
+ check we already know both files are on the same device. So it just
+ 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
the same file. */
if ((removepc || dstpc->exists ())
&& !oldpc.isdir ()
- && dstpc->fs_serial_number () == oldpc.fs_serial_number ()
&& NT_SUCCESS (NtQueryInformationFile (fh, &io, &ofsi, sizeof ofsi,
FileStandardInformation))
&& ofsi.NumberOfLinks > 1
@@ -2440,6 +2438,18 @@ retry:
}
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 ())
{
/* Workaround depressing NFS bug. FILE_RENAME_INFORMATION.FileName
@@ -2477,30 +2487,18 @@ retry:
while ((oldp = wcschr (++oldp, L'\\')) != NULL)
newp = wcpcpy (newp, L"..\\");
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);
memcpy (&pfri->FileName, newdst, pfri->FileNameLength);
}
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;
memcpy (&pfri->FileName, dstpc->get_nt_native_path ()->Buffer,
pfri->FileNameLength);
}
- pfri->ReplaceIfExists = TRUE;
- pfri->RootDirectory = NULL;
- status = NtSetInformationFile (fh, &io, pfri, size, FileRenameInformation);
+ status = NtSetInformationFile (fh, &io, pfri,
+ sizeof *pfri + pfri->FileNameLength,
+ FileRenameInformation);
/* This happens if the access rights don't allow deleting the destination.
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
@@ -2537,7 +2535,8 @@ retry:
}
}
if (NT_SUCCESS (status = unlink_nt (*dstpc)))
- status = NtSetInformationFile (fh, &io, pfri, size,
+ status = NtSetInformationFile (fh, &io, pfri,
+ sizeof *pfri + pfri->FileNameLength,
FileRenameInformation);
}
if (NT_SUCCESS (status))