On 2024-04-18 14:52, Sergei Trofimovich wrote:
$ clang simple.c -o simple && echo 42 | ./simple 1: ino=3009428657538693161 2: ino=3009428657538693161 3: ino=1568241705Note how stat() and fstat() don't agree on inode. Apparently it's documented in https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/fstat.2.html as BUGS Applying fstat to a socket (and thus to a pipe) returns a zero'd buffer, except for the blocksize field, and a unique device and inode number.
The BUGS note simply means that a pipe has a unique inode number, which is what we want. So that's not indicating any problem.
Oh, I see the problem now. For a socket or pipe, macOS fstat returns the full 64-bit inode number, whereas macOS stat returns only the low order 32 bits. In your example, 3009428657538693161 % (2**32) == 1568241705.
This is a kernel bug in macOS. Can you report it or otherwise arrange to have the kernel bug fixed? I expect that you have better connections with Apple than I do. A proposed patch (relative to xnu-10063.101.15) is attached; I have not tested it as I don't use macOS. Thanks.
Also, I am documenting this macOS bug in Gnulib by installing the second attached patch to Gnulib, and am cc'ing this email to bug-gnulib.
From 29345117a4cf85aceb88e3901758b19a4867062e Mon Sep 17 00:00:00 2001 From: Paul Eggert <egg...@cs.ucla.edu> Date: Fri, 19 Apr 2024 00:12:50 -0700 Subject: [PATCH] Fix bug with stat truncating pipe/socket st_ino Problem reported by Sergei Trofimovich in: https://bugs.gnu.org/70411 https://github.com/NixOS/nixpkgs/pull/300797 * bsd/miscfs/devfs/devfs_fdesc_support.c (fdesc_attr): Do not truncate inode numbers to 32 bits. --- bsd/miscfs/devfs/devfs_fdesc_support.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bsd/miscfs/devfs/devfs_fdesc_support.c b/bsd/miscfs/devfs/devfs_fdesc_support.c index a17c6992..b4a55103 100644 --- a/bsd/miscfs/devfs/devfs_fdesc_support.c +++ b/bsd/miscfs/devfs/devfs_fdesc_support.c @@ -437,10 +437,10 @@ fdesc_attr(int fd, struct vnode_attr *vap, vfs_context_t a_context) case DTYPE_PIPE: #if SOCKETS if (FILEGLOB_DTYPE(fp->fp_glob) == DTYPE_SOCKET) { - error = soo_stat((struct socket *)fp_get_data(fp), (void *)&stb, 0); + error = soo_stat((struct socket *)fp_get_data(fp), (void *)&stb, 1); } else #endif /* SOCKETS */ - error = pipe_stat((struct pipe *)fp_get_data(fp), (void *)&stb, 0); + error = pipe_stat((struct pipe *)fp_get_data(fp), (void *)&stb, 1); if (error == 0) { if (FILEGLOB_DTYPE(fp->fp_glob) == DTYPE_SOCKET) { -- 2.44.0
From c2174a623d33096b52f4d7fd2963f76acb3e301f Mon Sep 17 00:00:00 2001 From: Paul Eggert <egg...@cs.ucla.edu> Date: Fri, 19 Apr 2024 00:29:32 -0700 Subject: [PATCH] fstatat, stat: document macOS st_ino pipe bug * doc/posix-functions/fstatat.texi (fstatat): * doc/posix-functions/stat.texi (stat): Document macOS bug (see <https://bugs.gnu.org/70411>). --- ChangeLog | 7 +++++++ doc/posix-functions/fstatat.texi | 5 +++++ doc/posix-functions/stat.texi | 5 +++++ 3 files changed, 17 insertions(+) diff --git a/ChangeLog b/ChangeLog index 7ce75a98a9..1667f90c55 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2024-04-19 Paul Eggert <egg...@cs.ucla.edu> + + fstatat, stat: document macOS st_ino pipe bug + * doc/posix-functions/fstatat.texi (fstatat): + * doc/posix-functions/stat.texi (stat): + Document macOS bug (see <https://bugs.gnu.org/70411>). + 2024-04-18 Bruno Haible <br...@clisp.org> totalordermagl: Add tests. diff --git a/doc/posix-functions/fstatat.texi b/doc/posix-functions/fstatat.texi index e959a5cc73..90884e2eb1 100644 --- a/doc/posix-functions/fstatat.texi +++ b/doc/posix-functions/fstatat.texi @@ -40,5 +40,10 @@ This function does not fail when the second argument is an empty string on some platforms, even when @code{AT_EMPTY_PATH} is not used: glibc 2.7, Linux 2.6.38. @item +This function sets @code{st_ino} only to the low-order 32 bits of +the inode number of a socket or pipe, which thus can disagree +with the @code{st_ino} obtained by @code{fstat}: +macOS 14. +@item @xref{sys/stat.h}, for general portability problems with @code{struct stat}. @end itemize diff --git a/doc/posix-functions/stat.texi b/doc/posix-functions/stat.texi index f655451392..8afd3b17bb 100644 --- a/doc/posix-functions/stat.texi +++ b/doc/posix-functions/stat.texi @@ -50,6 +50,11 @@ Portability problems not fixed by Gnulib: Cygwin's @code{stat} function sometimes sets @code{errno} to @code{EACCES} when @code{ENOENT} would be more appropriate. @item +This function sets @code{st_ino} only to the low-order 32 bits of +the inode number of a socket or pipe, which thus can disagree +with the @code{st_ino} obtained by @code{fstat}: +macOS 14. +@item Because of the definition of @code{struct stat}, it is not possible to portably replace @code{stat} via an object-like macro. Therefore, expressions such as @code{(islnk ? lstat : stat) (name, buf)} are not -- 2.40.1