* m4/readlink.m4 (gl_FUNC_READLINK): Set REPLACE_READLINK to 1 on Cygwin.
* lib/readlink.c (rpl_readlink): On Cygwin, for /dev/* files, don't
return results that start with a backslash.
* tests/test-readlink.h (test_readlink): Add a test of /dev/null.
* tests/test-canonicalize-lgpl.c (main): Likewise.
* tests/test-canonicalize.c (main): Likewise.
* doc/posix-functions/readlink.texi: Mention the Cygwin bug.
+2024-06-03 Bruno Haible <bruno@clisp.org>
+
+ readlink: Work around a Cygwin 3.3.6 bug.
+ * m4/readlink.m4 (gl_FUNC_READLINK): Set REPLACE_READLINK to 1 on Cygwin.
+ * lib/readlink.c (rpl_readlink): On Cygwin, for /dev/* files, don't
+ return results that start with a backslash.
+ * tests/test-readlink.h (test_readlink): Add a test of /dev/null.
+ * tests/test-canonicalize-lgpl.c (main): Likewise.
+ * tests/test-canonicalize.c (main): Likewise.
+ * doc/posix-functions/readlink.texi: Mention the Cygwin bug.
+
2024-06-03 Bruno Haible <bruno@clisp.org>
nstrftime tests: Avoid some failures on native Windows.
On some platforms, this function returns @code{int} instead of
@code{ssize_t}:
glibc 2.4, FreeBSD 6.0, OpenBSD 6.7, Cygwin 1.5.x, 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:
/* Read the contents of a symbolic link.
- Copyright (C) 2003-2007, 2009-2023 Free Software Foundation, Inc.
+ Copyright (C) 2003-2007, 2009-2024 Free Software Foundation, Inc.
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
}
# endif
+# if defined __CYGWIN__
+ /* On Cygwin 3.3.6, readlink("/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;
}
-# readlink.m4 serial 17
-dnl Copyright (C) 2003, 2007, 2009-2023 Free Software Foundation, Inc.
+# readlink.m4 serial 18
+dnl Copyright (C) 2003, 2007, 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,
dnl with or without modifications, as long as this notice is preserved.
AC_DEFUN([gl_FUNC_READLINK],
[
AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
- AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+ AC_REQUIRE([AC_CANONICAL_HOST])
AC_CHECK_FUNCS_ONCE([readlink])
if test $ac_cv_func_readlink = no; then
HAVE_READLINK=0
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#include <unistd.h>
- /* Cause compilation failure if original declaration has wrong type. */
- ssize_t readlink (const char *, char *, size_t);]])],
+ /* Cause compilation failure if original declaration has
+ wrong type. */
+ ssize_t readlink (const char *, char *, size_t);
+ ]])
+ ],
[gl_cv_decl_readlink_works=yes], [gl_cv_decl_readlink_works=no])])
+
dnl Solaris 9 ignores trailing slash.
dnl FreeBSD 7.2 dereferences only one level of links with trailing slash.
AC_CACHE_CHECK([whether readlink handles trailing slash correctly],
AC_RUN_IFELSE(
[AC_LANG_PROGRAM(
[[#include <unistd.h>
-]], [[char buf[20];
- return readlink ("conftest.lnk2/", buf, sizeof buf) != -1;]])],
+ ]],
+ [[char buf[20];
+ return readlink ("conftest.lnk2/", buf, sizeof buf) != -1;
+ ]])
+ ],
[gl_cv_func_readlink_trailing_slash=yes],
[gl_cv_func_readlink_trailing_slash=no],
[case "$host_os" in
AC_RUN_IFELSE(
[AC_LANG_PROGRAM(
[[#include <unistd.h>
-]], [[char c;
- return readlink ("conftest.link", &c, 1) != 1;]])],
+ ]],
+ [[char c;
+ return readlink ("conftest.link", &c, 1) != 1;
+ ]])
+ ],
[gl_cv_func_readlink_truncate=yes],
[gl_cv_func_readlink_truncate=no],
[case "$host_os" in
REPLACE_READLINK=1
;;
esac
+
+ dnl On Cygwin 3.3.6, readlink("/dev/null") returns "\\Device\\Null", which
+ dnl is unusable.
+ case "$host_os" in
+ cygwin*)
+ REPLACE_READLINK=1
+ ;;
+ esac
fi
])
/* Test of execution of file name canonicalization.
- Copyright (C) 2007-2023 Free Software Foundation, Inc.
+ Copyright (C) 2007-2024 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
free (result2);
}
+#if !(defined _WIN32 && !defined __CYGWIN__)
+ /* Check a device file. */
+ {
+ char *result = canonicalize_file_name ("/dev/null");
+ ASSERT (result != NULL);
+ }
+#endif
/* Cleanup. */
ASSERT (remove (BASE "/droot") == 0);
/* Test of execution of file name canonicalization.
- Copyright (C) 2007-2023 Free Software Foundation, Inc.
+ Copyright (C) 2007-2024 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
free (result4);
}
+#if !(defined _WIN32 && !defined __CYGWIN__)
+ /* Check a device file. */
+ {
+ char *result1 = canonicalize_file_name ("/dev/null");
+ char *result2 = canonicalize_filename_mode ("/dev/null", CAN_ALL_BUT_LAST);
+ ASSERT (result1 != NULL);
+ ASSERT (result2 != NULL);
+ ASSERT (strcmp (result1, result2) == 0);
+ }
+#endif
+
/* Cleanup. */
ASSERT (remove (BASE "/droot") == 0);
ASSERT (remove (BASE "/d/1") == 0);
either left alone, or NUL-terminated. */
ASSERT (buf[len] == '\0' || buf[len] == (char) 0xff);
}
+ {
+ /* On Cygwin 3.3.6, readlink("/dev/null") returns "\\Device\\Null", which
+ is unusable. Verify that gnulib works around this nonsense. */
+ ssize_t result = func ("/dev/null", buf, sizeof buf);
+ ASSERT (result == -1 || buf[0] != '\\');
+ }
ASSERT (rmdir (BASE "dir") == 0);
ASSERT (unlink (BASE "link") == 0);