[newlib-cygwin/main] Cygwin: enable usage of FIFOs on NFS

Corinna Vinschen corinna@sourceware.org
Tue Sep 5 08:46:14 GMT 2023


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=622fb0776ea333dd708ff312f08ec98311138fbe

commit 622fb0776ea333dd708ff312f08ec98311138fbe
Author:     Corinna Vinschen <corinna@vinschen.de>
AuthorDate: Sat Aug 26 15:41:18 2023 +0200
Commit:     Corinna Vinschen <corinna@vinschen.de>
CommitDate: Mon Sep 4 10:41:02 2023 +0200

    Cygwin: enable usage of FIFOs on NFS
    
    FIFOs on NFS were never recogized as such in path handling.
    
    stat(2) indicated native FIFOs as FIFOs but the path handling
    code didn't set the matching values in the inner symlink checking
    code, so the followup behaviour was wrong.
    
    Basically for the same reason, Cygwin-created FIFOs were just treated
    as symlinks with weird content by stat(2) as well as path handling.
    
    Add code to enable both types of FIFOs on NFS as Cygwin FIFOs.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/fhandler/disk_file.cc | 22 +++++++++++++--------
 winsup/cygwin/path.cc               | 38 +++++++++++++++++++++++++++++++++----
 2 files changed, 48 insertions(+), 12 deletions(-)

diff --git a/winsup/cygwin/fhandler/disk_file.cc b/winsup/cygwin/fhandler/disk_file.cc
index 19c976aaae41..94f7ef566756 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 37e46c08ba89..c631fa8869b9 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;
 	}


More information about the Cygwin-cvs mailing list