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 ])