bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: canonicalize test failures on Cygwin


From: Bruno Haible
Subject: Re: canonicalize test failures on Cygwin
Date: Wed, 20 Jan 2021 09:31:54 +0100
User-agent: KMail/5.1.3 (Linux/4.4.0-197-generic; KDE/5.18.0; x86_64; ; )

Ken Brown wrote:
> I took a quick look, and it appears that this is a Cygwin bug in which 
> realpath() fails with ENOENT instead of ENOTDIR.

Yes, I confirm. POSIX
<https://pubs.opengroup.org/onlinepubs/9699919799/functions/realpath.html>
says that when one of the components "names an existing file that is neither
a directory nor a symbolic link to a directory", realpath() shall fail with
error ENOTDIR. Failing with error ENOENT is not allowed in this case.

Here's a patch that detects the issue at configure time and adds a workaround.
With it, the unit tests pass.


2021-01-20  Bruno Haible  <bruno@clisp.org>

        canonicalize-lgpl: Work around a Cygwin bug.
        * m4/canonicalize.m4 (gl_FUNC_REALPATH_WORKS): Test for lstat. Add a
        test case that involves a symbolic link to an existing file.
        * doc/posix-functions/realpath.texi: Mention the Cygwin bug.

diff --git a/doc/posix-functions/realpath.texi 
b/doc/posix-functions/realpath.texi
index a5b7c1d..dbeed3d 100644
--- a/doc/posix-functions/realpath.texi
+++ b/doc/posix-functions/realpath.texi
@@ -24,9 +24,9 @@ This function fails to detect trailing slashes on 
non-directories on
 some platforms:
 glibc 2.3.5, Mac OS X 10.13, OpenBSD 6.0.
 @item
-This function fails to recognize non-directories followed @samp{..} on
-some platforms:
-cygwin.
+This function fails to recognize non-directories or symlinks to non-directories
+followed by @samp{..} on some platforms:
+Cygwin 2.9.
 @item
 This function misbehaves on consecutive slashes on some platforms:
 musl libc 1.2.2, AIX 7.
diff --git a/m4/canonicalize.m4 b/m4/canonicalize.m4
index 6821c70..0dfb2da 100644
--- a/m4/canonicalize.m4
+++ b/m4/canonicalize.m4
@@ -1,4 +1,4 @@
-# canonicalize.m4 serial 36
+# canonicalize.m4 serial 37
 
 dnl Copyright (C) 2003-2007, 2009-2021 Free Software Foundation, Inc.
 
@@ -78,15 +78,20 @@ AC_DEFUN([gl_CANONICALIZE_LGPL_SEPARATE],
 # so is the latter.
 AC_DEFUN([gl_FUNC_REALPATH_WORKS],
 [
-  AC_CHECK_FUNCS_ONCE([realpath])
+  AC_CHECK_FUNCS_ONCE([realpath lstat])
   AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
   AC_CACHE_CHECK([whether realpath works], [gl_cv_func_realpath_works], [
     rm -rf conftest.a conftest.d
     touch conftest.a
+    # Assume that if we have lstat, we can also check symlinks.
+    if test $ac_cv_func_lstat = yes; then
+      ln -s conftest.a conftest.l
+    fi
     mkdir conftest.d
     AC_RUN_IFELSE([
       AC_LANG_PROGRAM([[
         ]GL_NOCRASH[
+        #include <errno.h>
         #include <stdlib.h>
         #include <string.h>
       ]], [[
@@ -98,17 +103,27 @@ AC_DEFUN([gl_FUNC_REALPATH_WORKS],
             result |= 1;
           free (name);
         }
+        /* This test fails on older versions of Cygwin.  */
         {
           char *name = realpath ("conftest.b/../conftest.a", NULL);
           if (name != NULL)
             result |= 2;
           free (name);
         }
+        /* This test fails on Cygwin 2.9.  */
+        #if HAVE_LSTAT
+        {
+          char *name = realpath ("conftest.l/../conftest.a", NULL);
+          if (name != NULL || errno != ENOTDIR)
+            result |= 4;
+          free (name);
+        }
+        #endif
         /* This test fails on Mac OS X 10.13, OpenBSD 6.0.  */
         {
           char *name = realpath ("conftest.a/", NULL);
           if (name != NULL)
-            result |= 4;
+            result |= 8;
           free (name);
         }
         /* This test fails on AIX 7, Solaris 10.  */
@@ -116,7 +131,7 @@ AC_DEFUN([gl_FUNC_REALPATH_WORKS],
           char *name1 = realpath (".", NULL);
           char *name2 = realpath ("conftest.d//./..", NULL);
           if (! name1 || ! name2 || strcmp (name1, name2))
-            result |= 8;
+            result |= 16;
           free (name1);
           free (name2);
         }
@@ -127,7 +142,7 @@ AC_DEFUN([gl_FUNC_REALPATH_WORKS],
         {
           char *name = realpath ("//", NULL);
           if (! name || strcmp (name, "/"))
-            result |= 16;
+            result |= 32;
           free (name);
         }
         #endif
@@ -136,7 +151,7 @@ AC_DEFUN([gl_FUNC_REALPATH_WORKS],
      ],
      [gl_cv_func_realpath_works=yes],
      [case $? in
-        16) gl_cv_func_realpath_works=nearly ;;
+        32) gl_cv_func_realpath_works=nearly ;;
         *)  gl_cv_func_realpath_works=no ;;
       esac
      ],
@@ -145,13 +160,15 @@ AC_DEFUN([gl_FUNC_REALPATH_WORKS],
         *-gnu* | gnu*) gl_cv_func_realpath_works="guessing yes" ;;
                        # Guess 'nearly' on musl systems.
         *-musl*)       gl_cv_func_realpath_works="guessing nearly" ;;
+                       # Guess no on Cygwin.
+        cygwin*)       gl_cv_func_realpath_works="guessing no" ;;
                        # Guess no on native Windows.
         mingw*)        gl_cv_func_realpath_works="guessing no" ;;
                        # If we don't know, obey --enable-cross-guesses.
         *)             gl_cv_func_realpath_works="$gl_cross_guess_normal" ;;
       esac
      ])
-    rm -rf conftest.a conftest.d
+    rm -rf conftest.a conftest.l conftest.d
   ])
   case "$gl_cv_func_realpath_works" in
     *yes)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]