4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-02-18 15:09:32 +08:00

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>
This commit is contained in:
Corinna Vinschen 2023-08-26 15:41:18 +02:00
parent 24b029ba8e
commit 622fb0776e
2 changed files with 48 additions and 12 deletions

View File

@ -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;

View File

@ -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;
}