* fhandler.h (fhandler_base::fstat_helper): Declare with additional

file attributes argument.
	* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Use
	file attributes evaluated from NtQueryFileInformation or
	FileInformationByHandle in call to fstat_helper.
	Set pc.fileattr from just evaluated file attributes here.
	(fhandler_base::fstat_by_name): Use file attributes evaluated from
	FindFileFirst or default attribute in call to fstat_helper.
	Set pc.fileattr from just evaluated file attributes here.
	(fhandler_base::fstat_helper): Use file attributes given as argument,
	not file attributes stored in this fhandler, since this information
	is potentially wrong.  Add comment to explain this.
	* path.h (has_attribute): New global inline function.
	(path_conv::set_attributes): New method to change fileattr.
This commit is contained in:
Corinna Vinschen 2005-09-22 15:52:02 +00:00
parent f3a61fc4aa
commit f3810c7281
4 changed files with 75 additions and 31 deletions

View File

@ -1,3 +1,20 @@
2005-09-22 Corinna Vinschen <corinna@vinschen.de>
* fhandler.h (fhandler_base::fstat_helper): Declare with additional
file attributes argument.
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Use
file attributes evaluated from NtQueryFileInformation or
FileInformationByHandle in call to fstat_helper.
Set pc.fileattr from just evaluated file attributes here.
(fhandler_base::fstat_by_name): Use file attributes evaluated from
FindFileFirst or default attribute in call to fstat_helper.
Set pc.fileattr from just evaluated file attributes here.
(fhandler_base::fstat_helper): Use file attributes given as argument,
not file attributes stored in this fhandler, since this information
is potentially wrong. Add comment to explain this.
* path.h (has_attribute): New global inline function.
(path_conv::set_attributes): New method to change fileattr.
2005-09-21 Christopher Faylor <cgf@timesys.com>
* cygthread.cc (cygthread::operator new): Just use getenv() to look for

View File

@ -272,7 +272,8 @@ class fhandler_base
LONGLONG nAllocSize,
DWORD nFileIndexHigh,
DWORD nFileIndexLow,
DWORD nNumberOfLinks)
DWORD nNumberOfLinks,
DWORD dwFileAttributes)
__attribute__ ((regparm (3)));
int __stdcall fstat_by_handle (struct __stat64 *buf) __attribute__ ((regparm (2)));
int __stdcall fstat_by_name (struct __stat64 *buf) __attribute__ ((regparm (2)));

View File

@ -124,22 +124,26 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf)
status = NtQueryInformationFile (get_handle (), &io, pfai, fai_size,
FileAllInformation);
if (NT_SUCCESS (status))
/* If the change time is 0, it's a file system which doesn't
support a change timestamp. In that case use the LastWriteTime
entry, as in other calls to fstat_helper. */
return fstat_helper (buf,
pfai->BasicInformation.ChangeTime.QuadPart ?
*(FILETIME *) &pfai->BasicInformation.ChangeTime :
*(FILETIME *) &pfai->BasicInformation.LastWriteTime,
*(FILETIME *) &pfai->BasicInformation.LastAccessTime,
*(FILETIME *) &pfai->BasicInformation.LastWriteTime,
pfvi->VolumeSerialNumber,
pfai->StandardInformation.EndOfFile.HighPart,
pfai->StandardInformation.EndOfFile.LowPart,
pfai->StandardInformation.AllocationSize.QuadPart,
pfai->InternalInformation.IndexNumber.HighPart,
pfai->InternalInformation.IndexNumber.LowPart,
pfai->StandardInformation.NumberOfLinks);
{
/* If the change time is 0, it's a file system which doesn't
support a change timestamp. In that case use the LastWriteTime
entry, as in other calls to fstat_helper. */
pc.set_attributes (pfai->BasicInformation.FileAttributes);
return fstat_helper (buf,
pfai->BasicInformation.ChangeTime.QuadPart ?
*(FILETIME *) &pfai->BasicInformation.ChangeTime :
*(FILETIME *) &pfai->BasicInformation.LastWriteTime,
*(FILETIME *) &pfai->BasicInformation.LastAccessTime,
*(FILETIME *) &pfai->BasicInformation.LastWriteTime,
pfvi->VolumeSerialNumber,
pfai->StandardInformation.EndOfFile.HighPart,
pfai->StandardInformation.EndOfFile.LowPart,
pfai->StandardInformation.AllocationSize.QuadPart,
pfai->InternalInformation.IndexNumber.HighPart,
pfai->InternalInformation.IndexNumber.LowPart,
pfai->StandardInformation.NumberOfLinks,
pfai->BasicInformation.FileAttributes);
}
debug_printf ("%u = NtQueryInformationFile)",
RtlNtStatusToDosError (status));
@ -160,6 +164,7 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf)
local.nFileSizeLow = 0;
}
pc.set_attributes (local.dwFileAttributes);
return fstat_helper (buf,
local.ftLastWriteTime, /* see fstat_helper comment */
local.ftLastAccessTime,
@ -170,7 +175,8 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf)
-1LL,
local.nFileIndexHigh,
local.nFileIndexLow,
local.nNumberOfLinks);
local.nNumberOfLinks,
local.dwFileAttributes);
}
int __stdcall
@ -189,6 +195,7 @@ fhandler_base::fstat_by_name (struct __stat64 *buf)
else if ((handle = FindFirstFile (pc, &local)) != INVALID_HANDLE_VALUE)
{
FindClose (handle);
pc.set_attributes (local.dwFileAttributes);
res = fstat_helper (buf,
local.ftLastWriteTime, /* see fstat_helper comment */
local.ftLastAccessTime,
@ -199,12 +206,14 @@ fhandler_base::fstat_by_name (struct __stat64 *buf)
-1LL,
0,
0,
1);
1,
local.dwFileAttributes);
}
else if (pc.isdir ())
{
FILETIME ft = {};
res = fstat_helper (buf, ft, ft, ft, pc.volser (), 0, 0, -1LL, 0, 0, 1);
res = fstat_helper (buf, ft, ft, ft, pc.volser (), 0, 0, -1LL, 0, 0, 1,
FILE_ATTRIBUTE_DIRECTORY);
}
else
{
@ -270,7 +279,11 @@ fhandler_base::fstat_fs (struct __stat64 *buf)
it's faked using the LastWriteTime entry from GetFileInformationByHandle
or FindFirstFile. We're deliberatly not using the creation time anymore
to simplify interaction with native Windows applications which choke on
creation times >= access or write times. */
creation times >= access or write times.
Note that the dwFileAttributes member of the file information evaluated
in the calling function is used here, not the pc.fileattr member, since
the latter might be old and not reflect the actual state of the file. */
int __stdcall
fhandler_base::fstat_helper (struct __stat64 *buf,
FILETIME ftChangeTime,
@ -282,7 +295,8 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
LONGLONG nAllocSize,
DWORD nFileIndexHigh,
DWORD nFileIndexLow,
DWORD nNumberOfLinks)
DWORD nNumberOfLinks,
DWORD dwFileAttributes)
{
IO_STATUS_BLOCK st;
FILE_COMPRESSION_INFORMATION fci;
@ -328,11 +342,11 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
/* A successful NtQueryInformationFile returns the allocation size
correctly for compressed and sparse files as well. */
buf->st_blocks = (nAllocSize + S_BLKSIZE - 1) / S_BLKSIZE;
else if (pc.has_attribute (FILE_ATTRIBUTE_COMPRESSED
| FILE_ATTRIBUTE_SPARSE_FILE)
&& get_io_handle () && !is_fs_special ()
&& !NtQueryInformationFile (get_io_handle (), &st, (PVOID) &fci,
sizeof fci, FileCompressionInformation))
else if (::has_attribute (dwFileAttributes, FILE_ATTRIBUTE_COMPRESSED
| FILE_ATTRIBUTE_SPARSE_FILE)
&& get_io_handle () && !is_fs_special ()
&& !NtQueryInformationFile (get_io_handle (), &st, (PVOID) &fci,
sizeof fci, FileCompressionInformation))
/* Otherwise we request the actual amount of bytes allocated for
compressed and sparsed files. */
buf->st_blocks = (fci.CompressedSize.QuadPart + S_BLKSIZE - 1) / S_BLKSIZE;
@ -357,11 +371,14 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
else if (pc.issocket ())
buf->st_mode = S_IFSOCK;
if (!get_file_attribute (pc.has_acls (), is_fs_special () ? NULL: get_io_handle (),
get_win32_name (), &buf->st_mode, &buf->st_uid, &buf->st_gid))
if (!get_file_attribute (pc.has_acls (),
is_fs_special () ? NULL: get_io_handle (),
get_win32_name (), &buf->st_mode,
&buf->st_uid, &buf->st_gid))
{
/* If read-only attribute is set, modify ntsec return value */
if (pc.has_attribute (FILE_ATTRIBUTE_READONLY) && !pc.issymlink ())
if (::has_attribute (dwFileAttributes, FILE_ATTRIBUTE_READONLY)
&& !pc.issymlink ())
buf->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
if (buf->st_mode & S_IFMT)
@ -378,7 +395,8 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
{
buf->st_mode |= STD_RBITS;
if (!pc.has_attribute (FILE_ATTRIBUTE_READONLY) && !pc.issymlink ())
if (::has_attribute (dwFileAttributes, FILE_ATTRIBUTE_READONLY)
&& !pc.issymlink ())
buf->st_mode |= STD_WBITS;
/* | S_IWGRP | S_IWOTH; we don't give write to group etc */

View File

@ -14,6 +14,13 @@ details. */
#include <fcntl.h>
#include <ntdef.h>
inline bool
has_attribute (DWORD attributes, DWORD attribs_to_test)
{
return attributes != INVALID_FILE_ATTRIBUTES
&& (attributes & attribs_to_test);
}
enum executable_states
{
is_executable,
@ -161,6 +168,7 @@ class path_conv
bool isro () const {return !!(path_flags & PATH_RO);}
bool exists () const {return fileattr != INVALID_FILE_ATTRIBUTES;}
bool has_attribute (DWORD x) const {return exists () && (fileattr & x);}
void set_attributes (DWORD x) {fileattr = x;}
int isdir () const {return has_attribute (FILE_ATTRIBUTE_DIRECTORY);}
executable_states exec_state ()
{