* lib/faccessat.c (LSTAT_FOLLOWS_SLASHED_SYMLINK): Default to 0.
(rpl_faccessat): Don’t mishandle empty string, or null pointer for
that matter.  Also, do not call fstatat if
LSTAT_FOLLOWS_SLASHED_SYMLINK, as there is no need in that case.
---
 ChangeLog       |  6 ++++++
 lib/faccessat.c | 28 ++++++++++++++++++----------
 2 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 731cb8bd53..f95316fada 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2026-06-16  Paul Eggert  <[email protected]>
 
+       faccessat: support "" and NULL file
+       * lib/faccessat.c (LSTAT_FOLLOWS_SLASHED_SYMLINK): Default to 0.
+       (rpl_faccessat): Don’t mishandle empty string, or null pointer for
+       that matter.  Also, do not call fstatat if
+       LSTAT_FOLLOWS_SLASHED_SYMLINK, as there is no need in that case.
+
        fcntl-h: glibc now has openat2
        * m4/fcntl_h.m4 (gl_FCNTL_H_DEFAULTS): HAVE_OPENAT2 is now 1,
        as glibc 2.43 (2026) supports it.
diff --git a/lib/faccessat.c b/lib/faccessat.c
index ee0205e397..ad5720236b 100644
--- a/lib/faccessat.c
+++ b/lib/faccessat.c
@@ -50,24 +50,32 @@ orig_faccessat (int fd, char const *name, int mode, int 
flag)
 # define access euidaccess
 #endif
 
+#ifndef LSTAT_FOLLOWS_SLASHED_SYMLINK
+# define LSTAT_FOLLOWS_SLASHED_SYMLINK 0
+#endif
+
 #if HAVE_FACCESSAT
 
 int
-rpl_faccessat (int fd, char const *file, int mode, int flag)
+rpl_faccessat (int fd, char const *file, int mode, int flags)
 {
-  int result = orig_faccessat (fd, file, mode, flag);
+  int result = orig_faccessat (fd, file, mode, flags);
 
-  if (file[strlen (file) - 1] == '/')
+  if (!LSTAT_FOLLOWS_SLASHED_SYMLINK && file)
     {
-      struct stat st;
-      int ret = fstatat (fd, file, &st, 0);
-      if (ret == 0 && !S_ISDIR (st.st_mode))
+      size_t len = strlen (file);
+      if (len && file[len - 1] == '/')
         {
-          errno = ENOTDIR;
-          return -1;
+          struct stat st;
+          int ret = fstatat (fd, file, &st, 0);
+          if (ret == 0 && !S_ISDIR (st.st_mode))
+            {
+              errno = ENOTDIR;
+              return -1;
+            }
+          if (result == 0)
+            result = ret;
         }
-      if (result == 0)
-        result = ret;
     }
 
   return result;
-- 
2.54.0


Reply via email to