]> Savannah Git Hosting - gnulib.git/commitdiff
access: Work around trailing slash bug on Mac OS X 10.5.
authorBruno Haible <bruno@clisp.org>
Tue, 3 Oct 2023 13:59:57 +0000 (15:59 +0200)
committerBruno Haible <bruno@clisp.org>
Tue, 3 Oct 2023 14:16:31 +0000 (16:16 +0200)
* m4/access.m4 (gl_FUNC_ACCESS): Test whether access honors a trailing
slash. Set REPLACE_ACCESS to 1 and define ACCESS_TRAILING_SLASH_BUG if
not.
* lib/access.c (access): Add an implementation for Unix-like platforms.
* tests/test-access.c (main): Test for result if the argument has a
trailing slash.
* modules/access-tests (Depends-on): Add 'symlink'.
* doc/posix-functions/access.texi: Mention the Mac OS X bug.

ChangeLog
doc/posix-functions/access.texi
lib/access.c
m4/access.m4
modules/access-tests
tests/test-access.c

index b9ced8b4aaaefa390845e39320d9854b950626e0..0c8d28f1139edbbbc9ad606a91ce18f2bb268121 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2023-10-03  Bruno Haible  <bruno@clisp.org>
+
+       access: Work around trailing slash bug on Mac OS X 10.5.
+       * m4/access.m4 (gl_FUNC_ACCESS): Test whether access honors a trailing
+       slash. Set REPLACE_ACCESS to 1 and define ACCESS_TRAILING_SLASH_BUG if
+       not.
+       * lib/access.c (access): Add an implementation for Unix-like platforms.
+       * tests/test-access.c (main): Test for result if the argument has a
+       trailing slash.
+       * modules/access-tests (Depends-on): Add 'symlink'.
+       * doc/posix-functions/access.texi: Mention the Mac OS X bug.
+
 2023-10-03  Bruno Haible  <bruno@clisp.org>
 
        update-copyright tests: Fix test failure (regression 2023-06-18).
index 8bfa2c1a67bf798a381a2b766cadf2104b5dfabc..fd114d300f239e97542db770af65e1cc77179faf 100644 (file)
@@ -11,6 +11,10 @@ Portability problems fixed by Gnulib:
 @item
 This function does not support the @code{X_OK} mode on some platforms:
 MSVC 14.
+@item
+This function does not reject trailing slashes on symlinks to non-directories
+on some platforms:
+Mac OS X 10.5.
 @end itemize
 
 Portability problems not fixed by Gnulib:
index e2c12b1f19f7bbcf22d695f2678ea716fcebe3f3..75d2148453c3c61f39e40914476e55878135b8ff 100644 (file)
 #include <unistd.h>
 
 #include <fcntl.h>
-#include <io.h>
+
+#if defined _WIN32 && ! defined __CYGWIN__
+
+# include <io.h>
 
 int
 access (const char *file, int mode)
@@ -29,3 +32,35 @@ access (const char *file, int mode)
     mode = (mode & ~X_OK) | R_OK;
   return _access (file, mode);
 }
+
+#else
+
+# include <errno.h>
+# include <string.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+
+int
+access (const char *file, int mode)
+# undef access
+{
+  int ret = access (file, mode);
+# if ACCESS_TRAILING_SLASH_BUG
+  if (ret == 0)
+    {
+      size_t file_len = strlen (file);
+      if (file_len > 0 && file[file_len - 1] == '/')
+        {
+          struct stat st;
+          if (stat (file, &st) == 0 && ! S_ISDIR (st.st_mode))
+            {
+              errno = ENOTDIR;
+              return -1;
+            }
+        }
+    }
+# endif
+  return ret;
+}
+
+#endif
index 259e2221fa384abf1a6a5a3e6a1a2dfa43a75b98..9fb9ee145efa30402c66bab55d1bf47f62ee37b1 100644 (file)
@@ -1,4 +1,4 @@
-# access.m4 serial 2
+# access.m4 serial 3
 dnl Copyright (C) 2019-2023 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -11,6 +11,55 @@ AC_DEFUN([gl_FUNC_ACCESS],
   dnl On native Windows, access (= _access) does not support the X_OK mode.
   dnl It works by chance on some versions of mingw.
   case "$host_os" in
-    mingw* | windows*) REPLACE_ACCESS=1 ;;
+    mingw* | windows*)
+      REPLACE_ACCESS=1
+      ;;
+    *)
+      dnl Mac OS X 10.5 mistakenly allows access("link-to-file/",amode).
+      AC_CHECK_FUNCS_ONCE([lstat])
+      AC_CACHE_CHECK([whether access honors trailing slash],
+        [gl_cv_func_access_slash_works],
+        [# Assume that if we have lstat, we can also check symlinks.
+         if test $ac_cv_func_lstat = yes; then
+           rm -rf conftest.f conftest.lnk
+           touch conftest.f || AC_MSG_ERROR([cannot create temporary files])
+           ln -s conftest.f conftest.lnk
+           AC_RUN_IFELSE(
+             [AC_LANG_PROGRAM([[
+                #include <unistd.h>
+                ]],
+                [[int result = 0;
+                  if (access ("conftest.lnk/", R_OK) == 0)
+                    result |= 1;
+                  return result;
+                ]])],
+             [gl_cv_func_access_slash_works=yes],
+             [gl_cv_func_access_slash_works=no],
+             dnl When crosscompiling, assume access is broken.
+             [case "$host_os" in
+                                   # Guess yes on Linux systems.
+                linux-* | linux)   gl_cv_func_access_slash_works="guessing yes" ;;
+                                   # Guess yes on systems that emulate the Linux system calls.
+                midipix*)          gl_cv_func_access_slash_works="guessing yes" ;;
+                                   # Guess yes on glibc systems.
+                *-gnu*)            gl_cv_func_access_slash_works="guessing yes" ;;
+                                   # If we don't know, obey --enable-cross-guesses.
+                *)                 gl_cv_func_access_slash_works="$gl_cross_guess_normal" ;;
+              esac
+             ])
+           rm -rf conftest.f conftest.lnk
+         else
+           gl_cv_func_access_slash_works="guessing yes"
+         fi
+      ])
+      case "$gl_cv_func_access_slash_works" in
+        *yes) ;;
+        *)
+          REPLACE_ACCESS=1
+          AC_DEFINE([ACCESS_TRAILING_SLASH_BUG], [1],
+            [Define if access does not correctly handle trailing slashes.])
+          ;;
+      esac
+      ;;
   esac
 ])
index 4b35c21150073a1eec2ffc477c26a1088724ebbe..78344887cda4ffe17e19708db7c5c166fbdf914f 100644 (file)
@@ -6,6 +6,7 @@ tests/macros.h
 Depends-on:
 creat
 root-uid
+symlink
 
 configure.ac:
 AC_CHECK_FUNCS_ONCE([geteuid])
index 5f9a4ad2160c42c5a55bdcd95dedcf3c0e2431aa..771678f0f750fa076cdc64258edb6fe5259598cb 100644 (file)
@@ -42,6 +42,7 @@ main ()
   unlink (BASE "f1");
   chmod (BASE "f2", 0600);
   unlink (BASE "f2");
+  unlink (BASE "sl");
 
   {
     errno = 0;
@@ -59,9 +60,31 @@ main ()
   {
     ASSERT (close (creat (BASE "f1", 0700)) == 0);
 
+    ASSERT (access (BASE "f1", F_OK) == 0);
     ASSERT (access (BASE "f1", R_OK) == 0);
     ASSERT (access (BASE "f1", W_OK) == 0);
     ASSERT (access (BASE "f1", X_OK) == 0);
+
+    ASSERT (access (BASE "f1/", F_OK) == -1);
+    ASSERT (errno == ENOTDIR);
+    ASSERT (access (BASE "f1/", R_OK) == -1);
+    ASSERT (errno == ENOTDIR);
+    ASSERT (access (BASE "f1/", W_OK) == -1);
+    ASSERT (errno == ENOTDIR);
+    ASSERT (access (BASE "f1/", X_OK) == -1);
+    ASSERT (errno == ENOTDIR);
+
+    if (symlink (BASE "f1", BASE "sl") == 0)
+      {
+        ASSERT (access (BASE "sl/", F_OK) == -1);
+        ASSERT (errno == ENOTDIR);
+        ASSERT (access (BASE "sl/", R_OK) == -1);
+        ASSERT (errno == ENOTDIR);
+        ASSERT (access (BASE "sl/", W_OK) == -1);
+        ASSERT (errno == ENOTDIR);
+        ASSERT (access (BASE "sl/", X_OK) == -1);
+        ASSERT (errno == ENOTDIR);
+      }
   }
   {
     ASSERT (close (creat (BASE "f2", 0600)) == 0);
@@ -90,6 +113,7 @@ main ()
   ASSERT (unlink (BASE "f1") == 0);
   ASSERT (chmod (BASE "f2", 0600) == 0);
   ASSERT (unlink (BASE "f2") == 0);
+  unlink (BASE "sl");
 
   return 0;
 }