I did:
>       * tests/test-readlink.h (test_readlink): Add a test of /dev/null.

and now I get a failure of test-readlinkat:

FAIL: test-readlinkat
=====================

../../gltests/test-readlink.h:120: assertion 'result == -1 || buf[0] != '\\'' 
failed
Stack trace:
0x40243d print_stack_trace
        ../../gllib/abort-debug.c:40
0x40243d _gl_pre_abort
        ../../gllib/abort-debug.c:81
0x402372 test_readlink
        ../../gltests/test-readlink.h:120
0x4127a0 main
        ../../gltests/test-readlinkat.c:75

This patch should fix it.


2024-06-03  Bruno Haible  <br...@clisp.org>

        readlinkat: Work around a Cygwin 3.3.6 bug.
        * m4/readlinkat.m4 (gl_FUNC_READLINKAT): Set REPLACE_READLINKAT to 1 on
        Cygwin.
        * lib/readlinkat.c (rpl_readlinkat): On Cygwin, for /dev/* files, don't
        return results that start with a backslash.
        * doc/posix-functions/readlinkat.texi: Mention the Cygwin bug.

diff --git a/doc/posix-functions/readlinkat.texi 
b/doc/posix-functions/readlinkat.texi
index 503de65e9e..2384bcb2c8 100644
--- a/doc/posix-functions/readlinkat.texi
+++ b/doc/posix-functions/readlinkat.texi
@@ -19,6 +19,10 @@
 On some platforms, this function returns @code{int} instead of
 @code{ssize_t}:
 AIX 7.1.
+@item
+For the file name @file{/dev/null}, this function returns @file{\Device\Null},
+which is unusable, on some platforms:
+Cygwin 3.3.6.
 @end itemize
 
 Portability problems mostly fixed by Gnulib:
diff --git a/lib/readlinkat.c b/lib/readlinkat.c
index faf85401ae..f4d64c0d13 100644
--- a/lib/readlinkat.c
+++ b/lib/readlinkat.c
@@ -79,6 +79,16 @@ rpl_readlinkat (int fd, char const *file, char *buf, size_t 
bufsize)
     }
 # endif
 
+# if defined __CYGWIN__
+  /* On Cygwin 3.3.6, readlinkat(AT_FDCWD,"/dev/null") returns 
"\\Device\\Null",
+     which is unusable.  Better fail with EINVAL.  */
+  if (r > 0 && strncmp (file, "/dev/", 5) == 0 && buf[0] == '\\')
+    {
+      errno = EINVAL;
+      return -1;
+    }
+# endif
+
   return r;
 }
 
diff --git a/m4/readlinkat.m4 b/m4/readlinkat.m4
index 8a33c16913..1f091e8b63 100644
--- a/m4/readlinkat.m4
+++ b/m4/readlinkat.m4
@@ -1,5 +1,5 @@
 # readlinkat.m4
-# serial 8
+# serial 9
 dnl Copyright (C) 2009-2024 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -27,9 +27,12 @@ AC_DEFUN([gl_FUNC_READLINKAT]
          [AC_LANG_PROGRAM(
            [[#include <unistd.h>
              /* Check whether original declaration has correct type.  */
-             ssize_t readlinkat (int, char const *, char *, size_t);]])],
+             ssize_t readlinkat (int, char const *, char *, size_t);
+           ]])
+         ],
          [gl_cv_decl_readlinkat_works=yes],
-         [gl_cv_decl_readlinkat_works=no])])
+         [gl_cv_decl_readlinkat_works=no])
+      ])
     # Assume readlinkat has the same bugs as readlink,
     # as is the case on OS X 10.10 with trailing slashes.
     case 
$gl_cv_decl_readlinkat_works,$gl_cv_func_readlink_trailing_slash,$gl_cv_func_readlink_truncate
 in
@@ -39,5 +42,13 @@ AC_DEFUN([gl_FUNC_READLINKAT]
         REPLACE_READLINKAT=1
         ;;
     esac
+
+    dnl On Cygwin 3.3.6, readlinkat(AT_FDCWD,"/dev/null") returns
+    dnl "\\Device\\Null", which is unusable.
+    case "$host_os" in
+      cygwin*)
+        REPLACE_READLINKAT=1
+        ;;
+    esac
   fi
 ])




Reply via email to