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
path: root/winsup
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2010-09-30 17:52:34 +0400
committerCorinna Vinschen <corinna@vinschen.de>2010-09-30 17:52:34 +0400
commit2d355410b7b59710e61b45e529900f9ebbd668e8 (patch)
tree2886afae145598a4242d7d59766c171e94494f99 /winsup
parentab3cd8885800a6fcf60b0d503b402d55202257c6 (diff)
* fhandler.cc: Drop including nfs.h.
* fhandler_disk_file.cc: Ditto. (fhandler_base::fstat_by_nfs_ea): Use fattr3 from path_conv member, unless called from fstat. * path.cc: Drop including nfs.h. (symlink_info::check): Rearrange definition of file info buffers. Fetch fattr3 info for files on NFS and store in conv_hdl for later use in fhandler_base::fstat_by_nfs_ea. Use fattr3 file type to recognize symlink on NFS and try to fetch symlink target only for actual symlinks. * path.h: Include nfs.h. (class path_conv_handle): Change file info storage to union of FILE_NETWORK_OPEN_INFORMATION and fattr3 structures. (path_conv_handle::fnoi): Align to aforementioned change. (path_conv_handle::nfsattr): New method. (path_conv::nfsattr): New method.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog19
-rw-r--r--winsup/cygwin/fhandler.cc1
-rw-r--r--winsup/cygwin/fhandler_disk_file.cc83
-rw-r--r--winsup/cygwin/path.cc43
-rw-r--r--winsup/cygwin/path.h32
5 files changed, 110 insertions, 68 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index c185a0a08..70ef991b1 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,24 @@
2010-09-30 Corinna Vinschen <corinna@vinschen.de>
+ * fhandler.cc: Drop including nfs.h.
+ * fhandler_disk_file.cc: Ditto.
+ (fhandler_base::fstat_by_nfs_ea): Use fattr3 from path_conv member,
+ unless called from fstat.
+ * path.cc: Drop including nfs.h.
+ (symlink_info::check): Rearrange definition of file info buffers.
+ Fetch fattr3 info for files on NFS and store in conv_hdl for later
+ use in fhandler_base::fstat_by_nfs_ea. Use fattr3 file type to
+ recognize symlink on NFS and try to fetch symlink target only for
+ actual symlinks.
+ * path.h: Include nfs.h.
+ (class path_conv_handle): Change file info storage to union of
+ FILE_NETWORK_OPEN_INFORMATION and fattr3 structures.
+ (path_conv_handle::fnoi): Align to aforementioned change.
+ (path_conv_handle::nfsattr): New method.
+ (path_conv::nfsattr): New method.
+
+2010-09-30 Corinna Vinschen <corinna@vinschen.de>
+
* path.cc (symlink_info::check): Remove erroneous assumption about
required permissions when reading NFS symlinks.
diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc
index ce5f79b2e..c97cc0139 100644
--- a/winsup/cygwin/fhandler.cc
+++ b/winsup/cygwin/fhandler.cc
@@ -28,7 +28,6 @@ details. */
#include "ntdll.h"
#include "cygtls.h"
#include "sigproc.h"
-#include "nfs.h"
static NO_COPY const int CHUNK_SIZE = 1024; /* Used for crlf conversions */
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
index 85be07c3d..7f314ed19 100644
--- a/winsup/cygwin/fhandler_disk_file.cc
+++ b/winsup/cygwin/fhandler_disk_file.cc
@@ -23,7 +23,6 @@ details. */
#include "pinfo.h"
#include "ntdll.h"
#include "tls_pbuf.h"
-#include "nfs.h"
#include "pwdgrp.h"
#include <winioctl.h>
@@ -303,51 +302,51 @@ fhandler_base::fstat_by_nfs_ea (struct __stat64 *buf)
struct {
FILE_GET_EA_INFORMATION fgei;
char buf[sizeof (NFS_V3_ATTR)];
- } fgei_buf;
-
- /* NFS stumbles over its own caching. If you write to the file,
- a subsequent fstat does not return the actual size of the file,
- but the size at the time the handle has been opened. Unless
- access through another handle invalidates the caching within the
- NFS client. */
- if (get_io_handle () && (get_access () & GENERIC_WRITE))
- FlushFileBuffers (get_io_handle ());
-
- fgei_buf.fgei.NextEntryOffset = 0;
- fgei_buf.fgei.EaNameLength = sizeof (NFS_V3_ATTR) - 1;
- stpcpy (fgei_buf.fgei.EaName, NFS_V3_ATTR);
- status = NtQueryEaFile (get_stat_handle (), &io,
- &ffei_buf.ffei, sizeof ffei_buf, TRUE,
- &fgei_buf.fgei, sizeof fgei_buf, NULL, TRUE);
- if (NT_SUCCESS (status))
+ } fgei_buf;
+ fattr3 *nfs_attr = pc.nfsattr ();
+
+ if (get_io_handle ())
{
- fattr3 *nfs_attr = (fattr3 *) (ffei_buf.ffei.EaName
- + ffei_buf.ffei.EaNameLength + 1);
- buf->st_dev = nfs_attr->fsid;
- buf->st_ino = nfs_attr->fileid;
- buf->st_mode = (nfs_attr->mode & 0xfff)
- | nfs_type_mapping[nfs_attr->type & 7];
- buf->st_nlink = nfs_attr->nlink;
- /* FIXME: How to convert UNIX uid/gid to Windows SIDs? */
+ /* NFS stumbles over its own caching. If you write to the file,
+ a subsequent fstat does not return the actual size of the file,
+ but the size at the time the handle has been opened. Unless
+ access through another handle invalidates the caching within the
+ NFS client. */
+ if (get_access () & GENERIC_WRITE)
+ FlushFileBuffers (get_io_handle ());
+
+ fgei_buf.fgei.NextEntryOffset = 0;
+ fgei_buf.fgei.EaNameLength = sizeof (NFS_V3_ATTR) - 1;
+ stpcpy (fgei_buf.fgei.EaName, NFS_V3_ATTR);
+ status = NtQueryEaFile (get_io_handle (), &io,
+ &ffei_buf.ffei, sizeof ffei_buf, TRUE,
+ &fgei_buf.fgei, sizeof fgei_buf, NULL, TRUE);
+ if (NT_SUCCESS (status))
+ nfs_attr = (fattr3 *) (ffei_buf.ffei.EaName
+ + ffei_buf.ffei.EaNameLength + 1);
+ }
+ buf->st_dev = nfs_attr->fsid;
+ buf->st_ino = nfs_attr->fileid;
+ buf->st_mode = (nfs_attr->mode & 0xfff)
+ | nfs_type_mapping[nfs_attr->type & 7];
+ buf->st_nlink = nfs_attr->nlink;
+ /* FIXME: How to convert UNIX uid/gid to Windows SIDs? */
#if 0
- buf->st_uid = nfs_attr->uid;
- buf->st_gid = nfs_attr->gid;
+ buf->st_uid = nfs_attr->uid;
+ buf->st_gid = nfs_attr->gid;
#else
- buf->st_uid = myself->uid;
- buf->st_gid = myself->gid;
+ buf->st_uid = myself->uid;
+ buf->st_gid = myself->gid;
#endif
- buf->st_rdev = makedev (nfs_attr->rdev.specdata1,
- nfs_attr->rdev.specdata2);
- buf->st_size = nfs_attr->size;
- buf->st_blksize = PREFERRED_IO_BLKSIZE;
- buf->st_blocks = nfs_attr->used / 512;
- buf->st_atim = nfs_attr->atime;
- buf->st_mtim = nfs_attr->mtime;
- buf->st_ctim = nfs_attr->ctime;
- return 0;
- }
- debug_printf ("%p = NtQueryEaFile(%S)", status, pc.get_nt_native_path ());
- return -1;
+ buf->st_rdev = makedev (nfs_attr->rdev.specdata1,
+ nfs_attr->rdev.specdata2);
+ buf->st_size = nfs_attr->size;
+ buf->st_blksize = PREFERRED_IO_BLKSIZE;
+ buf->st_blocks = nfs_attr->used / 512;
+ buf->st_atim = nfs_attr->atime;
+ buf->st_mtim = nfs_attr->mtime;
+ buf->st_ctim = nfs_attr->ctime;
+ return 0;
}
int __stdcall
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index c1f306efa..8c98e4dab 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -67,7 +67,6 @@
#include "cygtls.h"
#include "tls_pbuf.h"
#include "environ.h"
-#include "nfs.h"
#include <assert.h>
#include <ntdll.h>
#include <wchar.h>
@@ -2398,9 +2397,6 @@ restart:
}
}
- FILE_BASIC_INFORMATION fbi;
- PFILE_NETWORK_OPEN_INFORMATION pfnoi = conv_hdl.fnoi ();
-
if (NT_SUCCESS (status)
/* Check file system while we're having the file open anyway.
This speeds up path_conv noticably (~10%). */
@@ -2408,17 +2404,34 @@ restart:
{
if (fs.is_nfs ())
{
- /* NFS doesn't handle FileNetworkOpenInformation when called
- via NtQueryInformationFile (STATUS_INVALID_PARAMETER).
- Since we only need FileAttributes for NFS anyway, we just
- fetch the FileBasicInformation. */
- status = NtQueryInformationFile (h, &io, &fbi, sizeof fbi,
- FileBasicInformation);
+ struct {
+ FILE_FULL_EA_INFORMATION ffei;
+ char buf[sizeof (NFS_V3_ATTR) + sizeof (fattr3)];
+ } ffei_buf;
+ struct {
+ FILE_GET_EA_INFORMATION fgei;
+ char buf[sizeof (NFS_V3_ATTR)];
+ } fgei_buf;
+
+ fgei_buf.fgei.NextEntryOffset = 0;
+ fgei_buf.fgei.EaNameLength = sizeof (NFS_V3_ATTR) - 1;
+ stpcpy (fgei_buf.fgei.EaName, NFS_V3_ATTR);
+ status = NtQueryEaFile (h, &io, &ffei_buf.ffei, sizeof ffei_buf,
+ TRUE, &fgei_buf.fgei, sizeof fgei_buf,
+ NULL, TRUE);
if (NT_SUCCESS (status))
- fileattr = fbi.FileAttributes;
+ {
+ fattr3 *nfs_attr = (fattr3 *)
+ (ffei_buf.ffei.EaName + ffei_buf.ffei.EaNameLength + 1);
+ memcpy (conv_hdl.nfsattr (), nfs_attr, sizeof (fattr3));
+ fileattr = ((nfs_attr->type & 7) == NF3DIR)
+ ? FILE_ATTRIBUTE_DIRECTORY : 0;
+ }
}
else
{
+ PFILE_NETWORK_OPEN_INFORMATION pfnoi = conv_hdl.fnoi ();
+
status = NtQueryInformationFile (h, &io, pfnoi, sizeof *pfnoi,
FileNetworkOpenInformation);
if ((status == STATUS_INVALID_PARAMETER
@@ -2428,6 +2441,8 @@ restart:
/* This occurs when accessing SMB share root dirs hosted on
NT4 (STATUS_INVALID_PARAMETER), or when trying to access
SMB share root dirs from NT4 (STATUS_NOT_IMPLEMENTED). */
+ FILE_BASIC_INFORMATION fbi;
+
status = NtQueryInformationFile (h, &io, &fbi, sizeof fbi,
FileBasicInformation);
if (NT_SUCCESS (status))
@@ -2529,6 +2544,8 @@ restart:
}
else
{
+ PFILE_NETWORK_OPEN_INFORMATION pfnoi = conv_hdl.fnoi ();
+
fileattr = fdi_buf.fdi.FileAttributes;
memcpy (pfnoi, &fdi_buf.fdi.CreationTime, sizeof *pfnoi);
/* Amazing, but true: The FILE_NETWORK_OPEN_INFORMATION
@@ -2627,7 +2644,7 @@ restart:
else if (res)
{
/* A symlink is never a directory. */
- pfnoi->FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
+ conv_hdl.fnoi ()->FileAttributes &= ~FILE_ATTRIBUTE_DIRECTORY;
break;
}
}
@@ -2649,7 +2666,7 @@ restart:
/* If the file is on an NFS share and could be opened with extended
attributes, check if it's a symlink. Only files can be symlinks
(which can be symlinks to directories). */
- else if (fs.is_nfs () && !no_ea && !(fileattr & FILE_ATTRIBUTE_DIRECTORY))
+ else if (fs.is_nfs () && (conv_hdl.nfsattr ()->type & 7) == NF3LNK)
{
res = check_nfs_symlink (h);
if (res)
diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h
index fae721664..764381a4a 100644
--- a/winsup/cygwin/path.h
+++ b/winsup/cygwin/path.h
@@ -12,6 +12,7 @@ details. */
#include "devices.h"
#include "mount.h"
#include "cygheap_malloc.h"
+#include "nfs.h"
#include <sys/ioctl.h>
#include <fcntl.h>
@@ -96,17 +97,21 @@ class path_conv_handle
{
HANDLE hdl;
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;
+ union {
+ /* 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;
+ /* For NFS. */
+ fattr3 _fattr3;
+ } attribs;
public:
path_conv_handle () : hdl (NULL), acc (0) {}
inline void set (HANDLE h, ACCESS_MASK a) { hdl = h; acc = a; }
@@ -129,7 +134,9 @@ public:
inline HANDLE handle () const { return hdl; }
inline ACCESS_MASK access () const { return acc; }
inline struct _FILE_NETWORK_OPEN_INFORMATION *fnoi ()
- { return (struct _FILE_NETWORK_OPEN_INFORMATION *) &_fnoi; }
+ { return (struct _FILE_NETWORK_OPEN_INFORMATION *) &attribs._fnoi; }
+ inline struct fattr3 *nfsattr ()
+ { return (struct fattr3 *) &attribs._fattr3; }
};
class path_conv
@@ -321,6 +328,7 @@ class path_conv
HANDLE handle () const { return conv_handle.handle (); }
ACCESS_MASK access () const { return conv_handle.access (); }
struct _FILE_NETWORK_OPEN_INFORMATION *fnoi () { return conv_handle.fnoi (); }
+ struct fattr3 *nfsattr () { return conv_handle.nfsattr (); }
void reset_conv_handle () { conv_handle.set (NULL, 0); }
void close_conv_handle () { conv_handle.close (); }