From dc25619947e86c13ab7bad8ae6603b984025883f Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sat, 5 Dec 2020 00:17:02 +0100 Subject: [PATCH] utime: Fix a test failure on macOS 10.13. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Reported by Martin Storsjö in . * m4/utime.m4 (gl_FUNC_UTIME): Test whether utime handles trailing slashes on files. * lib/utime.c (utime): Add alternative implementation for Unix platforms. * modules/utime (Depends-on): Add stat. * doc/posix-functions/utime.texi: Mention the macOS 10.13 bug. * doc/posix-functions/lstat.texi: Mention that macOS 10.13 also has the trailing-slash bug. * doc/posix-functions/open.texi: Likewise. * doc/posix-functions/stat.texi: Likewise. * doc/posix-functions/symlink.texi: Likewise. --- ChangeLog | 17 ++++++++++++++ doc/posix-functions/lstat.texi | 2 +- doc/posix-functions/open.texi | 2 +- doc/posix-functions/stat.texi | 2 +- doc/posix-functions/symlink.texi | 2 +- doc/posix-functions/utime.texi | 4 ++++ lib/utime.c | 25 +++++++++++++++++++++ m4/utime.m4 | 48 +++++++++++++++++++++++++++++++++++++++- modules/utime | 1 + 9 files changed, 98 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5c19598b41..3de6368959 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2020-12-04 Bruno Haible + + utime: Fix a test failure on macOS 10.13. + Reported by Martin Storsjö in + . + * m4/utime.m4 (gl_FUNC_UTIME): Test whether utime handles trailing + slashes on files. + * lib/utime.c (utime): Add alternative implementation for Unix + platforms. + * modules/utime (Depends-on): Add stat. + * doc/posix-functions/utime.texi: Mention the macOS 10.13 bug. + * doc/posix-functions/lstat.texi: Mention that macOS 10.13 also has the + trailing-slash bug. + * doc/posix-functions/open.texi: Likewise. + * doc/posix-functions/stat.texi: Likewise. + * doc/posix-functions/symlink.texi: Likewise. + 2020-12-04 Paul Eggert intprops: update doc and mention Unisys diff --git a/doc/posix-functions/lstat.texi b/doc/posix-functions/lstat.texi index 1b1aff62cd..1a1ffb448e 100644 --- a/doc/posix-functions/lstat.texi +++ b/doc/posix-functions/lstat.texi @@ -24,7 +24,7 @@ Solaris 9. @item On some platforms, @code{lstat("file/",buf)} succeeds instead of failing with @code{ENOTDIR}. -Solaris 9. +Mac OS X 10.13, Solaris 9. @item On Solaris 11.4, when this function yields a timestamp with a nonpositive @code{tv_sec} value, @code{tv_nsec} might be in the range diff --git a/doc/posix-functions/open.texi b/doc/posix-functions/open.texi index d4767d9c7b..7e4f1874ee 100644 --- a/doc/posix-functions/open.texi +++ b/doc/posix-functions/open.texi @@ -19,7 +19,7 @@ correctly with files larger than 2 GB@. (Cf. @code{AC_SYS_LARGEFILE}.) This function does not fail when the file name argument ends in a slash and (without the slash) names a nonexistent file or a file that is not a directory, on some platforms: -FreeBSD 7.2, AIX 7.1, HP-UX 11.00, Solaris 9. +Mac OS X 10.13, FreeBSD 7.2, AIX 7.1, HP-UX 11.00, Solaris 9. @item This function does not support the @code{O_NONBLOCK} flag when it is defined by the gnulib module @code{nonblocking} on some platforms: diff --git a/doc/posix-functions/stat.texi b/doc/posix-functions/stat.texi index 27fbe278b3..1d1f927644 100644 --- a/doc/posix-functions/stat.texi +++ b/doc/posix-functions/stat.texi @@ -29,7 +29,7 @@ on directories such as @samp{C:\System Volume Information}. @item On some platforms, @code{stat("link-to-file/",buf)} succeeds instead of failing with @code{ENOTDIR}. -FreeBSD 7.2, AIX 7.1, Solaris 9, mingw64. +Mac OS X 10.13, FreeBSD 7.2, AIX 7.1, Solaris 9, mingw64. @item On some platforms, @code{stat(".",buf)} and @code{stat("./",buf)} give different results: diff --git a/doc/posix-functions/symlink.texi b/doc/posix-functions/symlink.texi index 88d1c772f0..3826ccfb81 100644 --- a/doc/posix-functions/symlink.texi +++ b/doc/posix-functions/symlink.texi @@ -11,7 +11,7 @@ Portability problems fixed by Gnulib: @item On some systems, @code{symlink(value,"name/")} mistakenly creates a symlink: -FreeBSD 7.2, AIX 7.1, Solaris 9. +Mac OS X 10.13, FreeBSD 7.2, AIX 7.1, Solaris 9. @item This function is missing on some platforms; however, the replacement always fails with @code{EPERM}: diff --git a/doc/posix-functions/utime.texi b/doc/posix-functions/utime.texi index d019c4a8ac..4e41e5d52c 100644 --- a/doc/posix-functions/utime.texi +++ b/doc/posix-functions/utime.texi @@ -16,6 +16,10 @@ mingw, MSVC 14 (when the environment variable @code{TZ} is set). On some platforms, the prototype for @code{utime} omits @code{const} for the second argument: mingw, MSVC 14. +@item +On some platforms, @code{utime("link-to-file/",buf)} succeeds instead +of failing with @code{ENOTDIR}. +Mac OS X 10.13. @end itemize Portability problems not fixed by Gnulib: diff --git a/lib/utime.c b/lib/utime.c index c35eb169e6..f6465a3cf1 100644 --- a/lib/utime.c +++ b/lib/utime.c @@ -259,4 +259,29 @@ utime (const char *name, const struct utimbuf *ts) } } +#else + +# include +# include "filename.h" + +int +utime (const char *name, const struct utimbuf *ts) +#undef utime +{ +# if REPLACE_FUNC_UTIME_FILE + /* macOS 10.13 mistakenly succeeds when given a symbolic link to a + non-directory with a trailing slash. */ + size_t len = strlen (name); + if (ISSLASH (name[len - 1])) + { + struct stat buf; + + if (stat (name, &buf) < 0) + return -1; + } +# endif /* REPLACE_FUNC_UTIME_FILE */ + + return utime (name, ts); +} + #endif diff --git a/m4/utime.m4 b/m4/utime.m4 index f0a8235552..3d2e13cb08 100644 --- a/m4/utime.m4 +++ b/m4/utime.m4 @@ -1,4 +1,4 @@ -# utime.m4 serial 2 +# utime.m4 serial 3 dnl Copyright (C) 2017-2020 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -8,6 +8,7 @@ AC_DEFUN([gl_FUNC_UTIME], [ AC_REQUIRE([gl_UTIME_H_DEFAULTS]) AC_REQUIRE([AC_CANONICAL_HOST]) + AC_CHECK_FUNCS_ONCE([lstat]) case "$host_os" in mingw*) dnl On this platform, the original utime() or _utime() produces @@ -21,6 +22,51 @@ AC_DEFUN([gl_FUNC_UTIME], AC_CHECK_FUNCS([utime]) if test $ac_cv_func_utime = no; then HAVE_UTIME=0 + else + dnl On macOS 10.13, utime("link-to-file/", NULL) mistakenly succeeds. + AC_CACHE_CHECK([whether utime handles trailing slashes on files], + [gl_cv_func_utime_file_slash], + [touch conftest.tmp + # Assume that if we have lstat, we can also check symlinks. + if test $ac_cv_func_lstat = yes; then + ln -s conftest.tmp conftest.lnk + fi + AC_RUN_IFELSE( + [AC_LANG_PROGRAM( + [[#include + #include + ]], + [[int result = 0; + if (!utime ("conftest.tmp/", NULL)) + result |= 1; + #if HAVE_LSTAT + if (!utime ("conftest.lnk/", NULL)) + result |= 2; + #endif + return result; + ]])], + [gl_cv_func_utime_file_slash=yes], + [gl_cv_func_utime_file_slash=no], + [case "$host_os" in + # Guess yes on Linux systems. + linux-* | linux) gl_cv_func_utime_file_slash="guessing yes" ;; + # Guess yes on glibc systems. + *-gnu* | gnu*) gl_cv_func_utime_file_slash="guessing yes" ;; + # Guess no on macOS. + darwin*) gl_cv_func_utime_file_slash="guessing no" ;; + # If we don't know, obey --enable-cross-guesses. + *) gl_cv_func_utime_file_slash="$gl_cross_guess_normal" ;; + esac + ]) + rm -f conftest.tmp conftest.lnk + ]) + case $gl_cv_func_stat_file_slash in + *no) + REPLACE_UTIME=1 + AC_DEFINE([REPLACE_FUNC_UTIME_FILE], [1], + [Define to 1 if utime needs help when passed a file name with a trailing slash]) + ;; + esac fi ;; esac diff --git a/modules/utime b/modules/utime index 0fc34ebdc9..d1975f47b3 100644 --- a/modules/utime +++ b/modules/utime @@ -10,6 +10,7 @@ utime-h time filename [test $HAVE_UTIME = 0 || test $REPLACE_UTIME = 1] malloca [test $HAVE_UTIME = 0 || test $REPLACE_UTIME = 1] +stat [test $HAVE_UTIME = 0 || test $REPLACE_UTIME = 1] configure.ac: gl_FUNC_UTIME -- 2.11.4.GIT