aboutsummaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/fhandler/disk_file.cc22
-rw-r--r--winsup/cygwin/path.cc38
2 files changed, 48 insertions, 12 deletions
diff --git a/winsup/cygwin/fhandler/disk_file.cc b/winsup/cygwin/fhandler/disk_file.cc
index 19c976a..94f7ef5 100644
--- a/winsup/cygwin/fhandler/disk_file.cc
+++ b/winsup/cygwin/fhandler/disk_file.cc
@@ -210,13 +210,14 @@ fhandler_base::fstat_by_nfs_ea (struct stat *buf)
cyg_ldap cldap;
bool ldap_open = false;
- if (get_handle ())
+ /* 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. Skip this for Cygwin-created Symlinks playing FIFOs
+ (this sets the filler1 member to NF3FIFO). */
+ if (get_handle () && nfs_attr->filler1 != NF3FIFO)
{
- /* 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_handle ());
pc.get_finfo (get_handle ());
@@ -357,8 +358,13 @@ fhandler_base::fstat_fs (struct stat *buf)
if (get_stat_handle ())
{
- if (!nohandle () && (!is_fs_special () || get_flags () & O_PATH))
- res = pc.fs_is_nfs () ? fstat_by_nfs_ea (buf) : fstat_by_handle (buf);
+ if (!nohandle ())
+ {
+ if (pc.fs_is_nfs ())
+ res = fstat_by_nfs_ea (buf);
+ else if (!is_fs_special () || get_flags () & O_PATH)
+ res = fstat_by_handle (buf);
+ }
if (res)
res = fstat_by_name (buf);
return res;
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 37e46c0..c631fa8 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -3513,11 +3513,41 @@ 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 () && (conv_hdl.nfsattr ()->type & 7) == NF3LNK)
+ attributes, check if it's a symlink or FIFO. */
+ else if (fs.is_nfs ())
{
- res = check_nfs_symlink (h);
+ /* Make sure filler1 is 0, so we can use it safely as a marker. */
+ conv_hdl.nfsattr ()->filler1 = 0;
+ switch (conv_hdl.nfsattr ()->type & 7)
+ {
+ case NF3LNK:
+ res = check_nfs_symlink (h);
+ /* Enable Cygwin-created FIFOs to be recognized as FIFOs.
+ We have to overwrite the NFS fattr3 data, otherwise the
+ info returned by Cygwin's stat will still claim the file
+ is a symlink. */
+ if (res && contents[0] == ':' && contents[1] == '\\'
+ && parse_device (contents) && major == _major (FH_FIFO))
+ {
+ conv_hdl.nfsattr ()->type = NF3FIFO;
+ conv_hdl.nfsattr ()->mode = mode;
+ conv_hdl.nfsattr ()->size = 0;
+ /* Marker for fhandler_base::fstat_by_nfs_ea not to override
+ the cached fattr3 data with fresh data from the filesystem,
+ even if the handle is used for other purposes than stat. */
+ conv_hdl.nfsattr ()->filler1 = NF3FIFO;
+ }
+ break;
+ case NF3FIFO:
+ /* Enable real FIFOs recognized as such. */
+ major = _major (FH_FIFO);
+ minor = _minor (FH_FIFO);
+ mode = S_IFIFO | (conv_hdl.nfsattr ()->mode & ~S_IFMT);
+ isdevice = true;
+ break;
+ default:
+ break;
+ }
if (res)
break;
}