* fhandler.h (class fhandler_base): Change inheritance of fstat_helper
and fstat_by_... methods to private. (fhandler_base::fstat_helper): Drop all redundant arguments. * fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Drop call to fstat_by_nfs_ea here. Drop fetching basic file information. Drop setting file attributes. Accommodate change in fstat_helper call. (fhandler_base::fstat_by_name): Simplify. Only fetch directory information to get the inode number. Drop setting file attributes. Accommodate change in fstat_helper call. (fhandler_base::fstat_fs): Call fstat_by_nfs_ea if on NFS. (fhandler_base::fstat_helper): Drop all redundant arguments. Use information already collected in the fhandler. Move heading comment into code and drop dwFileAttributes comment. * mmap.cc (mmap64): Call fstat_fs rather than fstat_by_handle. * mount.cc (fs_info::update): Note that has_buggy_basic_info is unused. * path.cc (symlink_info::check_reparse_point): Add comment. (symlink_info::check): Fetch FileNetworkOpenInformation rather than FileBasicInformation throughout, except on NFS. Explain why. Store FILE_NETWORK_OPEN_INFORMATION in conv_hdl. Remove FILE_ATTRIBUTE_DIRECTORY attribute in conv_hdl for reparse point symlinks. * path.h (class path_conv_handle): Add FILE_NETWORK_OPEN_INFORMATION member _fnoi. (path_conv_handle::fnoi): New accessor method for _fnoi. (path_conv::fnoi): New accessor method for cubv_hdl._fnoi. * fhandler_tty.cc (fhandler_tty_slave::init): Use tty::setpgid method.
This commit is contained in:
parent
f7382efe27
commit
c80480bfa0
|
@ -1,3 +1,33 @@
|
||||||
|
2010-09-13 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* fhandler.h (class fhandler_base): Change inheritance of fstat_helper
|
||||||
|
and fstat_by_... methods to private.
|
||||||
|
(fhandler_base::fstat_helper): Drop all redundant arguments.
|
||||||
|
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Drop call
|
||||||
|
to fstat_by_nfs_ea here. Drop fetching basic file information.
|
||||||
|
Drop setting file attributes. Accommodate change in fstat_helper call.
|
||||||
|
(fhandler_base::fstat_by_name): Simplify. Only fetch directory
|
||||||
|
information to get the inode number. Drop setting file attributes.
|
||||||
|
Accommodate change in fstat_helper call.
|
||||||
|
(fhandler_base::fstat_fs): Call fstat_by_nfs_ea if on NFS.
|
||||||
|
(fhandler_base::fstat_helper): Drop all redundant arguments. Use
|
||||||
|
information already collected in the fhandler. Move heading comment
|
||||||
|
into code and drop dwFileAttributes comment.
|
||||||
|
* mmap.cc (mmap64): Call fstat_fs rather than fstat_by_handle.
|
||||||
|
* mount.cc (fs_info::update): Note that has_buggy_basic_info is unused.
|
||||||
|
* path.cc (symlink_info::check_reparse_point): Add comment.
|
||||||
|
(symlink_info::check): Fetch FileNetworkOpenInformation rather than
|
||||||
|
FileBasicInformation throughout, except on NFS. Explain why. Store
|
||||||
|
FILE_NETWORK_OPEN_INFORMATION in conv_hdl. Remove
|
||||||
|
FILE_ATTRIBUTE_DIRECTORY attribute in conv_hdl for reparse point
|
||||||
|
symlinks.
|
||||||
|
* path.h (class path_conv_handle): Add FILE_NETWORK_OPEN_INFORMATION
|
||||||
|
member _fnoi.
|
||||||
|
(path_conv_handle::fnoi): New accessor method for _fnoi.
|
||||||
|
(path_conv::fnoi): New accessor method for cubv_hdl._fnoi.
|
||||||
|
|
||||||
|
* fhandler_tty.cc (fhandler_tty_slave::init): Use tty::setpgid method.
|
||||||
|
|
||||||
2010-09-12 Corinna Vinschen <corinna@vinschen.de>
|
2010-09-12 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* sec_acl.cc (acl_worker): Remove.
|
* sec_acl.cc (acl_worker): Remove.
|
||||||
|
|
|
@ -293,21 +293,14 @@ class fhandler_base
|
||||||
int close_fs () { return fhandler_base::close (); }
|
int close_fs () { return fhandler_base::close (); }
|
||||||
virtual int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
virtual int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||||
int __stdcall fstat_fs (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
int __stdcall fstat_fs (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||||
|
private:
|
||||||
int __stdcall fstat_helper (struct __stat64 *buf,
|
int __stdcall fstat_helper (struct __stat64 *buf,
|
||||||
PLARGE_INTEGER ChangeTime,
|
DWORD nNumberOfLinks)
|
||||||
PLARGE_INTEGER LastAccessTime,
|
__attribute__ ((regparm (3)));
|
||||||
PLARGE_INTEGER LastWriteTime,
|
|
||||||
PLARGE_INTEGER CreationTime,
|
|
||||||
DWORD dwVolumeSerialNumber,
|
|
||||||
ULONGLONG nFileSize,
|
|
||||||
LONGLONG nAllocSize,
|
|
||||||
ULONGLONG nFileIndex,
|
|
||||||
DWORD nNumberOfLinks,
|
|
||||||
DWORD dwFileAttributes)
|
|
||||||
__attribute__ ((regparm (3)));
|
|
||||||
int __stdcall fstat_by_nfs_ea (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
int __stdcall fstat_by_nfs_ea (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||||
int __stdcall fstat_by_handle (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
int __stdcall fstat_by_handle (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||||
int __stdcall fstat_by_name (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
int __stdcall fstat_by_name (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||||
|
public:
|
||||||
virtual int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
|
virtual int __stdcall fstatvfs (struct statvfs *buf) __attribute__ ((regparm (2)));
|
||||||
int utimens_fs (const struct timespec *) __attribute__ ((regparm (2)));
|
int utimens_fs (const struct timespec *) __attribute__ ((regparm (2)));
|
||||||
virtual int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
|
virtual int __stdcall fchmod (mode_t mode) __attribute__ ((regparm (1)));
|
||||||
|
|
|
@ -345,43 +345,17 @@ fhandler_base::fstat_by_nfs_ea (struct __stat64 *buf)
|
||||||
int __stdcall
|
int __stdcall
|
||||||
fhandler_base::fstat_by_handle (struct __stat64 *buf)
|
fhandler_base::fstat_by_handle (struct __stat64 *buf)
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
|
||||||
IO_STATUS_BLOCK io;
|
|
||||||
|
|
||||||
if (pc.fs_is_nfs ())
|
|
||||||
return fstat_by_nfs_ea (buf);
|
|
||||||
|
|
||||||
/* Don't use FileAllInformation info class. It returns a pathname rather
|
/* Don't use FileAllInformation info class. It returns a pathname rather
|
||||||
than a filename, so it needs a really big buffer for no good reason
|
than a filename, so it needs a really big buffer for no good reason
|
||||||
since we don't need the name anyway. So we just call the three info
|
since we don't need the name anyway. So we just call the three info
|
||||||
classes necessary to get all information required by stat(2). */
|
classes necessary to get all information required by stat(2). */
|
||||||
|
|
||||||
union {
|
|
||||||
FILE_BASIC_INFORMATION fbi;
|
|
||||||
FILE_NETWORK_OPEN_INFORMATION fnoi;
|
|
||||||
} fi;
|
|
||||||
FILE_STANDARD_INFORMATION fsi;
|
FILE_STANDARD_INFORMATION fsi;
|
||||||
FILE_INTERNAL_INFORMATION fii;
|
FILE_INTERNAL_INFORMATION fii;
|
||||||
|
|
||||||
HANDLE h = get_stat_handle ();
|
HANDLE h = get_stat_handle ();
|
||||||
|
NTSTATUS status = 0;
|
||||||
|
IO_STATUS_BLOCK io;
|
||||||
|
|
||||||
if (pc.has_buggy_basic_info ())
|
|
||||||
{
|
|
||||||
status = NtQueryInformationFile (h, &io, &fi, sizeof fi,
|
|
||||||
FileNetworkOpenInformation);
|
|
||||||
/* The timestamps are in the same relative memory location, only
|
|
||||||
the DOS attributes have to be moved. */
|
|
||||||
fi.fbi.FileAttributes = fi.fnoi.FileAttributes;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
status = NtQueryInformationFile (h, &io, &fi.fbi,
|
|
||||||
sizeof fi.fbi, FileBasicInformation);
|
|
||||||
if (!NT_SUCCESS (status))
|
|
||||||
{
|
|
||||||
debug_printf ("%p = NtQueryInformationFile(%S, FileBasicInformation)",
|
|
||||||
status, pc.get_nt_native_path ());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
status = NtQueryInformationFile (h, &io, &fsi, sizeof fsi,
|
status = NtQueryInformationFile (h, &io, &fsi, sizeof fsi,
|
||||||
FileStandardInformation);
|
FileStandardInformation);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
|
@ -402,26 +376,7 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf)
|
||||||
}
|
}
|
||||||
ino = fii.FileId.QuadPart;
|
ino = fii.FileId.QuadPart;
|
||||||
}
|
}
|
||||||
/* If the change time is 0, it's a file system which doesn't
|
return fstat_helper (buf, fsi.NumberOfLinks);
|
||||||
support a change timestamp. In that case use the LastWriteTime
|
|
||||||
entry, as in other calls to fstat_helper. */
|
|
||||||
if (pc.is_rep_symlink ())
|
|
||||||
fi.fbi.FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
|
|
||||||
/* Only copy attributes if not a device root dir. */
|
|
||||||
if (!(pc.file_attributes () & FILE_ATTRIBUTE_DEVICE))
|
|
||||||
pc.file_attributes (fi.fbi.FileAttributes);
|
|
||||||
return fstat_helper (buf,
|
|
||||||
fi.fbi.ChangeTime.QuadPart ? &fi.fbi.ChangeTime
|
|
||||||
: &fi.fbi.LastWriteTime,
|
|
||||||
&fi.fbi.LastAccessTime,
|
|
||||||
&fi.fbi.LastWriteTime,
|
|
||||||
&fi.fbi.CreationTime,
|
|
||||||
get_dev (),
|
|
||||||
fsi.EndOfFile.QuadPart,
|
|
||||||
fsi.AllocationSize.QuadPart,
|
|
||||||
ino,
|
|
||||||
fsi.NumberOfLinks,
|
|
||||||
fi.fbi.FileAttributes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int __stdcall
|
int __stdcall
|
||||||
|
@ -437,76 +392,35 @@ fhandler_base::fstat_by_name (struct __stat64 *buf)
|
||||||
FILE_ID_BOTH_DIR_INFORMATION fdi;
|
FILE_ID_BOTH_DIR_INFORMATION fdi;
|
||||||
WCHAR buf[NAME_MAX + 1];
|
WCHAR buf[NAME_MAX + 1];
|
||||||
} fdi_buf;
|
} fdi_buf;
|
||||||
LARGE_INTEGER FileId;
|
|
||||||
|
|
||||||
RtlSplitUnicodePath (pc.get_nt_native_path (), &dirname, &basename);
|
if (!ino && wincap.has_fileid_dirinfo () && !pc.has_buggy_fileid_dirinfo ())
|
||||||
InitializeObjectAttributes (&attr, &dirname, pc.objcaseinsensitive (),
|
|
||||||
NULL, NULL);
|
|
||||||
if (!NT_SUCCESS (status = NtOpenFile (&dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
|
|
||||||
&attr, &io, FILE_SHARE_VALID_FLAGS,
|
|
||||||
FILE_SYNCHRONOUS_IO_NONALERT
|
|
||||||
| FILE_OPEN_FOR_BACKUP_INTENT
|
|
||||||
| FILE_DIRECTORY_FILE)))
|
|
||||||
{
|
{
|
||||||
debug_printf ("%p = NtOpenFile(%S)", status, pc.get_nt_native_path ());
|
RtlSplitUnicodePath (pc.get_nt_native_path (), &dirname, &basename);
|
||||||
goto too_bad;
|
InitializeObjectAttributes (&attr, &dirname, pc.objcaseinsensitive (),
|
||||||
|
NULL, NULL);
|
||||||
|
status = NtOpenFile (&dir, SYNCHRONIZE | FILE_LIST_DIRECTORY,
|
||||||
|
&attr, &io, FILE_SHARE_VALID_FLAGS,
|
||||||
|
FILE_SYNCHRONOUS_IO_NONALERT
|
||||||
|
| FILE_OPEN_FOR_BACKUP_INTENT
|
||||||
|
| FILE_DIRECTORY_FILE);
|
||||||
|
if (!NT_SUCCESS (status))
|
||||||
|
debug_printf ("%p = NtOpenFile(%S)", status,
|
||||||
|
pc.get_nt_native_path ());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = NtQueryDirectoryFile (dir, NULL, NULL, NULL, &io,
|
||||||
|
&fdi_buf.fdi, sizeof fdi_buf,
|
||||||
|
FileIdBothDirectoryInformation,
|
||||||
|
TRUE, &basename, TRUE);
|
||||||
|
NtClose (dir);
|
||||||
|
if (!NT_SUCCESS (status))
|
||||||
|
debug_printf ("%p = NtQueryDirectoryFile(%S)", status,
|
||||||
|
pc.get_nt_native_path ());
|
||||||
|
else
|
||||||
|
ino = fdi_buf.fdi.FileId.QuadPart;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (wincap.has_fileid_dirinfo () && !pc.has_buggy_fileid_dirinfo ()
|
return fstat_helper (buf, 1);
|
||||||
&& NT_SUCCESS (status = NtQueryDirectoryFile (dir, NULL, NULL, NULL, &io,
|
|
||||||
&fdi_buf.fdi, sizeof fdi_buf,
|
|
||||||
FileIdBothDirectoryInformation,
|
|
||||||
TRUE, &basename, TRUE)))
|
|
||||||
FileId = fdi_buf.fdi.FileId;
|
|
||||||
else if (NT_SUCCESS (status = NtQueryDirectoryFile (dir, NULL, NULL, NULL,
|
|
||||||
&io, &fdi_buf.fdi,
|
|
||||||
sizeof fdi_buf,
|
|
||||||
FileBothDirectoryInformation,
|
|
||||||
TRUE, &basename, TRUE)))
|
|
||||||
FileId.QuadPart = 0; /* get_ino is called in fstat_helper. */
|
|
||||||
if (!NT_SUCCESS (status))
|
|
||||||
{
|
|
||||||
debug_printf ("%p = NtQueryDirectoryFile(%S)", status,
|
|
||||||
pc.get_nt_native_path ());
|
|
||||||
NtClose (dir);
|
|
||||||
goto too_bad;
|
|
||||||
}
|
|
||||||
NtClose (dir);
|
|
||||||
/* 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. */
|
|
||||||
if (pc.is_rep_symlink ())
|
|
||||||
fdi_buf.fdi.FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
|
|
||||||
/* Only copy attributes if not a device root dir. */
|
|
||||||
if (!(pc.file_attributes () & FILE_ATTRIBUTE_DEVICE))
|
|
||||||
pc.file_attributes (fdi_buf.fdi.FileAttributes);
|
|
||||||
return fstat_helper (buf,
|
|
||||||
fdi_buf.fdi.ChangeTime.QuadPart
|
|
||||||
? &fdi_buf.fdi.ChangeTime : &fdi_buf.fdi.LastWriteTime,
|
|
||||||
&fdi_buf.fdi.LastAccessTime,
|
|
||||||
&fdi_buf.fdi.LastWriteTime,
|
|
||||||
&fdi_buf.fdi.CreationTime,
|
|
||||||
pc.fs_serial_number (),
|
|
||||||
fdi_buf.fdi.EndOfFile.QuadPart,
|
|
||||||
fdi_buf.fdi.AllocationSize.QuadPart,
|
|
||||||
FileId.QuadPart,
|
|
||||||
1,
|
|
||||||
fdi_buf.fdi.FileAttributes);
|
|
||||||
|
|
||||||
too_bad:
|
|
||||||
LARGE_INTEGER ft;
|
|
||||||
/* Arbitrary value: 2006-12-01 */
|
|
||||||
RtlSecondsSince1970ToTime (1164931200L, &ft);
|
|
||||||
return fstat_helper (buf,
|
|
||||||
&ft,
|
|
||||||
&ft,
|
|
||||||
&ft,
|
|
||||||
&ft,
|
|
||||||
0,
|
|
||||||
0ULL,
|
|
||||||
-1LL,
|
|
||||||
0ULL,
|
|
||||||
1,
|
|
||||||
pc.file_attributes ());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int __stdcall
|
int __stdcall
|
||||||
|
@ -519,7 +433,7 @@ fhandler_base::fstat_fs (struct __stat64 *buf)
|
||||||
if (get_stat_handle ())
|
if (get_stat_handle ())
|
||||||
{
|
{
|
||||||
if (!nohandle () && !is_fs_special ())
|
if (!nohandle () && !is_fs_special ())
|
||||||
res = fstat_by_handle (buf);
|
res = pc.fs_is_nfs () ? fstat_by_nfs_ea (buf) : fstat_by_handle (buf);
|
||||||
if (res)
|
if (res)
|
||||||
res = fstat_by_name (buf);
|
res = fstat_by_name (buf);
|
||||||
return res;
|
return res;
|
||||||
|
@ -540,7 +454,7 @@ fhandler_base::fstat_fs (struct __stat64 *buf)
|
||||||
Since fhandler_base::open only calls CloseHandle if !nohandle,
|
Since fhandler_base::open only calls CloseHandle if !nohandle,
|
||||||
we have to set it to false before calling close and restore
|
we have to set it to false before calling close and restore
|
||||||
the state afterwards. */
|
the state afterwards. */
|
||||||
res = fstat_by_handle (buf);
|
res = pc.fs_is_nfs () ? fstat_by_nfs_ea (buf) : fstat_by_handle (buf);
|
||||||
bool no_handle = nohandle ();
|
bool no_handle = nohandle ();
|
||||||
nohandle (false);
|
nohandle (false);
|
||||||
close_fs ();
|
close_fs ();
|
||||||
|
@ -553,39 +467,26 @@ fhandler_base::fstat_fs (struct __stat64 *buf)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The ChangeTime is taken from the NTFS ChangeTime entry, if reading
|
|
||||||
the file information using NtQueryInformationFile succeeded. If not,
|
|
||||||
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.
|
|
||||||
|
|
||||||
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
|
int __stdcall
|
||||||
fhandler_base::fstat_helper (struct __stat64 *buf,
|
fhandler_base::fstat_helper (struct __stat64 *buf,
|
||||||
PLARGE_INTEGER ChangeTime,
|
DWORD nNumberOfLinks)
|
||||||
PLARGE_INTEGER LastAccessTime,
|
|
||||||
PLARGE_INTEGER LastWriteTime,
|
|
||||||
PLARGE_INTEGER CreationTime,
|
|
||||||
DWORD dwVolumeSerialNumber,
|
|
||||||
ULONGLONG nFileSize,
|
|
||||||
LONGLONG nAllocSize,
|
|
||||||
ULONGLONG nFileIndex,
|
|
||||||
DWORD nNumberOfLinks,
|
|
||||||
DWORD dwFileAttributes)
|
|
||||||
{
|
{
|
||||||
IO_STATUS_BLOCK st;
|
IO_STATUS_BLOCK st;
|
||||||
FILE_COMPRESSION_INFORMATION fci;
|
FILE_COMPRESSION_INFORMATION fci;
|
||||||
HANDLE h = get_stat_handle ();
|
HANDLE h = get_stat_handle ();
|
||||||
|
PFILE_NETWORK_OPEN_INFORMATION pfnoi = pc.fnoi ();
|
||||||
|
ULONG attributes = pc.file_attributes ();
|
||||||
|
|
||||||
to_timestruc_t ((PFILETIME) LastAccessTime, &buf->st_atim);
|
to_timestruc_t ((PFILETIME) &pfnoi->LastAccessTime, &buf->st_atim);
|
||||||
to_timestruc_t ((PFILETIME) LastWriteTime, &buf->st_mtim);
|
to_timestruc_t ((PFILETIME) &pfnoi->LastWriteTime, &buf->st_mtim);
|
||||||
to_timestruc_t ((PFILETIME) ChangeTime, &buf->st_ctim);
|
/* If the ChangeTime is 0, the underlying FS doesn't support this timestamp
|
||||||
to_timestruc_t ((PFILETIME) CreationTime, &buf->st_birthtim);
|
(FAT for instance). If so, it's faked using LastWriteTime. */
|
||||||
buf->st_rdev = buf->st_dev = dwVolumeSerialNumber;
|
to_timestruc_t (pfnoi->ChangeTime.QuadPart ? (PFILETIME) &pfnoi->ChangeTime
|
||||||
buf->st_size = (_off64_t) nFileSize;
|
: (PFILETIME) &pfnoi->LastWriteTime,
|
||||||
|
&buf->st_ctim);
|
||||||
|
to_timestruc_t ((PFILETIME) &pfnoi->CreationTime, &buf->st_birthtim);
|
||||||
|
buf->st_rdev = buf->st_dev = get_dev ();
|
||||||
|
buf->st_size = (_off64_t) pfnoi->EndOfFile.QuadPart;
|
||||||
/* The number of links to a directory includes the number of subdirectories
|
/* The number of links to a directory includes the number of subdirectories
|
||||||
in the directory, since all those subdirectories point to it. However,
|
in the directory, since all those subdirectories point to it. However,
|
||||||
this is painfully slow, so we do without it. */
|
this is painfully slow, so we do without it. */
|
||||||
|
@ -596,19 +497,20 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Enforce namehash as inode number on untrusted file systems. */
|
/* Enforce namehash as inode number on untrusted file systems. */
|
||||||
if (nFileIndex && pc.isgood_inode (nFileIndex))
|
if (ino && pc.isgood_inode (ino))
|
||||||
buf->st_ino = (__ino64_t) nFileIndex;
|
buf->st_ino = (__ino64_t) ino;
|
||||||
else
|
else
|
||||||
buf->st_ino = get_ino ();
|
buf->st_ino = get_ino ();
|
||||||
|
|
||||||
buf->st_blksize = PREFERRED_IO_BLKSIZE;
|
buf->st_blksize = PREFERRED_IO_BLKSIZE;
|
||||||
|
|
||||||
if (nAllocSize >= 0LL)
|
if (pfnoi->AllocationSize.QuadPart >= 0LL)
|
||||||
/* A successful NtQueryInformationFile returns the allocation size
|
/* A successful NtQueryInformationFile returns the allocation size
|
||||||
correctly for compressed and sparse files as well. */
|
correctly for compressed and sparse files as well. */
|
||||||
buf->st_blocks = (nAllocSize + S_BLKSIZE - 1) / S_BLKSIZE;
|
buf->st_blocks = (pfnoi->AllocationSize.QuadPart + S_BLKSIZE - 1)
|
||||||
else if (::has_attribute (dwFileAttributes, FILE_ATTRIBUTE_COMPRESSED
|
/ S_BLKSIZE;
|
||||||
| FILE_ATTRIBUTE_SPARSE_FILE)
|
else if (::has_attribute (attributes, FILE_ATTRIBUTE_COMPRESSED
|
||||||
|
| FILE_ATTRIBUTE_SPARSE_FILE)
|
||||||
&& h && !is_fs_special ()
|
&& h && !is_fs_special ()
|
||||||
&& !NtQueryInformationFile (h, &st, (PVOID) &fci, sizeof fci,
|
&& !NtQueryInformationFile (h, &st, (PVOID) &fci, sizeof fci,
|
||||||
FileCompressionInformation))
|
FileCompressionInformation))
|
||||||
|
@ -641,7 +543,7 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
|
||||||
&buf->st_mode, &buf->st_uid, &buf->st_gid))
|
&buf->st_mode, &buf->st_uid, &buf->st_gid))
|
||||||
{
|
{
|
||||||
/* If read-only attribute is set, modify ntsec return value */
|
/* If read-only attribute is set, modify ntsec return value */
|
||||||
if (::has_attribute (dwFileAttributes, FILE_ATTRIBUTE_READONLY)
|
if (::has_attribute (attributes, FILE_ATTRIBUTE_READONLY)
|
||||||
&& !pc.isdir () && !pc.issymlink ())
|
&& !pc.isdir () && !pc.issymlink ())
|
||||||
buf->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
|
buf->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
|
||||||
|
|
||||||
|
@ -660,7 +562,7 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
|
||||||
{
|
{
|
||||||
buf->st_mode |= STD_RBITS;
|
buf->st_mode |= STD_RBITS;
|
||||||
|
|
||||||
if (!::has_attribute (dwFileAttributes, FILE_ATTRIBUTE_READONLY))
|
if (!::has_attribute (attributes, FILE_ATTRIBUTE_READONLY))
|
||||||
buf->st_mode |= STD_WBITS;
|
buf->st_mode |= STD_WBITS;
|
||||||
/* | S_IWGRP | S_IWOTH; we don't give write to group etc */
|
/* | S_IWGRP | S_IWOTH; we don't give write to group etc */
|
||||||
|
|
||||||
|
|
|
@ -717,7 +717,7 @@ fhandler_tty_slave::init (HANDLE f, DWORD a, mode_t)
|
||||||
tty process group leader.
|
tty process group leader.
|
||||||
TODO: Investigate how SIGTTIN should be handled with pure-windows
|
TODO: Investigate how SIGTTIN should be handled with pure-windows
|
||||||
programs. */
|
programs. */
|
||||||
tc->pgid = myself->pgid;
|
tc->setpgid (myself->pgid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f != INVALID_HANDLE_VALUE)
|
if (f != INVALID_HANDLE_VALUE)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* mmap.cc
|
/* mmap.cc
|
||||||
|
|
||||||
Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
|
Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005,
|
||||||
2006, 2007 Red Hat, Inc.
|
2006, 2007, 2008, 2009, 2010 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
@ -865,7 +865,7 @@ mmap64 (void *addr, size_t len, int prot, int flags, int fd, _off64_t off)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fh->fstat_by_handle (&st))
|
if (fh->fstat_fs (&st))
|
||||||
{
|
{
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
goto out;
|
goto out;
|
||||||
|
|
|
@ -381,7 +381,8 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
|
||||||
Therefore, for NWFS we have to fallback to the
|
Therefore, for NWFS we have to fallback to the
|
||||||
FileNetworkOpenInformation info class. Unfortunately we can't
|
FileNetworkOpenInformation info class. Unfortunately we can't
|
||||||
use FileNetworkOpenInformation all the time since that fails on
|
use FileNetworkOpenInformation all the time since that fails on
|
||||||
other filesystems like NFS. */
|
other filesystems like NFS.
|
||||||
|
UNUSED, but keep in for information purposes. */
|
||||||
has_buggy_basic_info (is_nwfs ());
|
has_buggy_basic_info (is_nwfs ());
|
||||||
/* Netapp ans NWFS are too dumb to allow non-DOS filesystems
|
/* Netapp ans NWFS are too dumb to allow non-DOS filesystems
|
||||||
containing trailing dots and spaces when accessed from Windows
|
containing trailing dots and spaces when accessed from Windows
|
||||||
|
|
|
@ -1946,6 +1946,7 @@ symlink_info::check_reparse_point (HANDLE h)
|
||||||
sys_wcstombs (srcbuf, SYMLINK_MAX + 7, subst.Buffer,
|
sys_wcstombs (srcbuf, SYMLINK_MAX + 7, subst.Buffer,
|
||||||
subst.Length / sizeof (WCHAR));
|
subst.Length / sizeof (WCHAR));
|
||||||
pflags |= PATH_SYMLINK | PATH_REP;
|
pflags |= PATH_SYMLINK | PATH_REP;
|
||||||
|
/* A symlink is never a directory. */
|
||||||
fileattr &= ~FILE_ATTRIBUTE_DIRECTORY;
|
fileattr &= ~FILE_ATTRIBUTE_DIRECTORY;
|
||||||
return posixify (srcbuf);
|
return posixify (srcbuf);
|
||||||
}
|
}
|
||||||
|
@ -2238,7 +2239,6 @@ symlink_info::check (char *path, const suffix_info *suffixes, fs_info &fs,
|
||||||
UNICODE_STRING upath;
|
UNICODE_STRING upath;
|
||||||
OBJECT_ATTRIBUTES attr;
|
OBJECT_ATTRIBUTES attr;
|
||||||
IO_STATUS_BLOCK io;
|
IO_STATUS_BLOCK io;
|
||||||
FILE_BASIC_INFORMATION fbi;
|
|
||||||
suffix_scan suffix;
|
suffix_scan suffix;
|
||||||
|
|
||||||
const ULONG ci_flag = cygwin_shared->obcaseinsensitive
|
const ULONG ci_flag = cygwin_shared->obcaseinsensitive
|
||||||
|
@ -2409,16 +2409,34 @@ restart:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FILE_BASIC_INFORMATION fbi;
|
||||||
|
PFILE_NETWORK_OPEN_INFORMATION pfnoi = conv_hdl.fnoi ();
|
||||||
|
|
||||||
if (NT_SUCCESS (status)
|
if (NT_SUCCESS (status)
|
||||||
/* Check file system while we're having the file open anyway.
|
/* Check file system while we're having the file open anyway.
|
||||||
This speeds up path_conv noticably (~10%). */
|
This speeds up path_conv noticably (~10%). */
|
||||||
&& (fs.inited () || fs.update (&upath, h))
|
&& (fs.inited () || fs.update (&upath, h)))
|
||||||
&& NT_SUCCESS (status = fs.has_buggy_basic_info ()
|
{
|
||||||
? NtQueryAttributesFile (&attr, &fbi)
|
if (fs.is_nfs ())
|
||||||
: NtQueryInformationFile (h, &io, &fbi, sizeof fbi,
|
{
|
||||||
FileBasicInformation)))
|
/* NFS doesn't handle FileNetworkOpenInformation when called
|
||||||
fileattr = fbi.FileAttributes;
|
via NtQueryInformationFile (STATUS_INVALID_PARAMETER).
|
||||||
else
|
Since we only need FileAttributes for NFS anyway, we just
|
||||||
|
fetch the FileBasicInformation. */
|
||||||
|
status = NtQueryInformationFile (h, &io, &fbi, sizeof fbi,
|
||||||
|
FileBasicInformation);
|
||||||
|
if (NT_SUCCESS (status))
|
||||||
|
fileattr = fbi.FileAttributes;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = NtQueryInformationFile (h, &io, pfnoi, sizeof *pfnoi,
|
||||||
|
FileNetworkOpenInformation);
|
||||||
|
if (NT_SUCCESS (status))
|
||||||
|
fileattr = pfnoi->FileAttributes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
debug_printf ("%p = NtQueryInformationFile (%S)", status, &upath);
|
debug_printf ("%p = NtQueryInformationFile (%S)", status, &upath);
|
||||||
fileattr = INVALID_FILE_ATTRIBUTES;
|
fileattr = INVALID_FILE_ATTRIBUTES;
|
||||||
|
@ -2504,7 +2522,10 @@ restart:
|
||||||
fileattr = 0;
|
fileattr = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fileattr = fdi_buf.fdi.FileAttributes;
|
{
|
||||||
|
fileattr = fdi_buf.fdi.FileAttributes;
|
||||||
|
memcpy (pfnoi, &fdi_buf.fdi.CreationTime, sizeof *pfnoi);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ext_tacked_on = !!*ext_here;
|
ext_tacked_on = !!*ext_here;
|
||||||
goto file_not_symlink;
|
goto file_not_symlink;
|
||||||
|
@ -2590,7 +2611,11 @@ restart:
|
||||||
pflags &= ~PC_KEEP_HANDLE;
|
pflags &= ~PC_KEEP_HANDLE;
|
||||||
}
|
}
|
||||||
else if (res)
|
else if (res)
|
||||||
break;
|
{
|
||||||
|
/* A symlink is never a directory. */
|
||||||
|
pfnoi->FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is the old Cygwin method creating symlinks. A symlink will
|
/* This is the old Cygwin method creating symlinks. A symlink will
|
||||||
|
|
|
@ -89,10 +89,24 @@ enum path_types
|
||||||
PATH_SOCKET = 0x40000000
|
PATH_SOCKET = 0x40000000
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class symlink_info;
|
||||||
|
struct _FILE_NETWORK_OPEN_INFORMATION;
|
||||||
|
|
||||||
class path_conv_handle
|
class path_conv_handle
|
||||||
{
|
{
|
||||||
HANDLE hdl;
|
HANDLE hdl;
|
||||||
ACCESS_MASK acc;
|
ACCESS_MASK acc;
|
||||||
|
/* Identical to FILE_NETWORK_OPEN_INFORMATION. We don't want to pull in
|
||||||
|
ntdll.h here, though. */
|
||||||
|
struct {
|
||||||
|
LARGE_INTEGER CreationTime;
|
||||||
|
LARGE_INTEGER LastAccessTime;
|
||||||
|
LARGE_INTEGER LastWriteTime;
|
||||||
|
LARGE_INTEGER ChangeTime;
|
||||||
|
LARGE_INTEGER AllocationSize;
|
||||||
|
LARGE_INTEGER EndOfFile;
|
||||||
|
ULONG FileAttributes;
|
||||||
|
} _fnoi;
|
||||||
public:
|
public:
|
||||||
path_conv_handle () : hdl (NULL), acc (0) {}
|
path_conv_handle () : hdl (NULL), acc (0) {}
|
||||||
inline void set (HANDLE h, ACCESS_MASK a) { hdl = h; acc = a; }
|
inline void set (HANDLE h, ACCESS_MASK a) { hdl = h; acc = a; }
|
||||||
|
@ -114,10 +128,10 @@ public:
|
||||||
}
|
}
|
||||||
inline HANDLE handle () const { return hdl; }
|
inline HANDLE handle () const { return hdl; }
|
||||||
inline ACCESS_MASK access () const { return acc; }
|
inline ACCESS_MASK access () const { return acc; }
|
||||||
|
inline struct _FILE_NETWORK_OPEN_INFORMATION *fnoi ()
|
||||||
|
{ return (struct _FILE_NETWORK_OPEN_INFORMATION *) &_fnoi; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class symlink_info;
|
|
||||||
|
|
||||||
class path_conv
|
class path_conv
|
||||||
{
|
{
|
||||||
DWORD fileattr;
|
DWORD fileattr;
|
||||||
|
@ -287,6 +301,7 @@ class path_conv
|
||||||
|
|
||||||
HANDLE handle () const { return conv_handle.handle (); }
|
HANDLE handle () const { return conv_handle.handle (); }
|
||||||
ACCESS_MASK access () const { return conv_handle.access (); }
|
ACCESS_MASK access () const { return conv_handle.access (); }
|
||||||
|
struct _FILE_NETWORK_OPEN_INFORMATION *fnoi () { return conv_handle.fnoi (); }
|
||||||
void reset_conv_handle () { conv_handle.set (NULL, 0); }
|
void reset_conv_handle () { conv_handle.set (NULL, 0); }
|
||||||
void close_conv_handle () { conv_handle.close (); }
|
void close_conv_handle () { conv_handle.close (); }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue