* lib/openat2.c (dirstat) [FSTAT_O_PATH_BUG]: Fix typo (a missing
arg) in workaround for this bug in Linux kernel 2.6.39 (2011)
through 3.5.7 (2012).  Evidently nobody compiles on these old
platforms, but we might as well fix the code if we’re going to
have it at all.
---
 ChangeLog     |  7 +++++++
 lib/openat2.c | 32 ++++++++++++++++++++++++++------
 2 files changed, 33 insertions(+), 6 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 8b4a239eaf..025f560095 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2026-06-18  Paul Eggert  <[email protected]>
 
+       openat2: fix typo for circa-2012 Linux
+       * lib/openat2.c (dirstat) [FSTAT_O_PATH_BUG]: Fix typo (a missing
+       arg) in workaround for this bug in Linux kernel 2.6.39 (2011)
+       through 3.5.7 (2012).  Evidently nobody compiles on these old
+       platforms, but we might as well fix the code if we’re going to
+       have it at all.
+
        fstatat: support NULL if AT_EMPTY_PATH
        On platforms that define AT_EMPTY_PATH, allow a null pointer to be
        passed as a file name.  This is GNU behavior as of glibc 2.41 +
diff --git a/lib/openat2.c b/lib/openat2.c
index 8c722427f7..ff8ce30263 100644
--- a/lib/openat2.c
+++ b/lib/openat2.c
@@ -44,6 +44,7 @@
 #endif
 
 /* FSTAT_O_PATH_BUG is true if fstat fails on O_PATH file descriptors.
+   On these platforms fstatat with AT_EMPTY_PATH and "" similarly fails.
    Although it can be dicey to use static checks for Linux kernel versions,
    due to the dubious practice of building on newer kernels for older ones,
    do it here anyway as the buggy kernels are rare (all EOLed by 2016)
@@ -56,6 +57,10 @@
 # define FSTAT_O_PATH_BUG false
 #endif
 
+#ifndef GNULIB_FSTATAT
+# define GNULIB_FSTATAT 0
+#endif
+
 #ifndef E2BIG
 # define E2BIG EINVAL
 #endif
@@ -150,14 +155,29 @@ maybe_grow (char **buf, idx_t bufsize, char *stackbuf,
 static int
 dirstat (int dirfd, struct stat *st)
 {
-  /* Use fstatat only if fstat is buggy.  fstatat is a bit slower,
-     and using it only on buggy hosts means openat2 need not depend on
-     Gnulib's fstatat module, as all systems with the fstat bug have
-     an fstatat that works well enough. */
 #if FSTAT_O_PATH_BUG
-  return fstatat (dirfd, ".", st);
+  /* Use fstatat with "." to work around a bug in fstat (and in
+     fstatat with "" and AT_EMPTY_PATH) in Linux kernels 2.6.39 (2011)
+     through 3.5.7 (2012).  This workaround does not depend on
+     Gnulib's fstatat module, as all systems with the fstat bug have
+     an fstatat that works well enough here.  */
+  return fstatat (dirfd, ".", st, 0);
+
 #else
-  return dirfd < 0 ? stat (".", st) : fstat (dirfd, st);
+
+  if (0 <= dirfd)
+    return fstat (dirfd, st);
+
+# if AT_EMPTY_PATH
+  /* Prefer fstatat with AT_EMPTY_PATH if available, as this avoids
+     admittedly-unlikely problems when the working directory is not
+     searchable.  This workaround does not depend on Gnulib's fstatat
+     module, as all systems with AT_EMPTY_PATH and without
+     FSTAT_O_PATH_BUG should work well enough here.  */
+  return fstatat (dirfd, GNULIB_FSTATAT ? NULL : "", st, AT_EMPTY_PATH);
+# else
+  return stat (".", st);
+# endif
 #endif
 }
 
-- 
2.54.0


Reply via email to