+2025-03-17 Collin Funk <collin.funk1@gmail.com>
+
+ utimensat: Work around a GNU/Hurd bug.
+ * lib/utimensat.c (rpl_utimensat) [__gnu_hurd__]: Check for out of range
+ tv_nsec values.
+ * m4/utimensat.m4 (gl_FUNC_UTIMENSAT): Likewise. Guess that utimensat
+ doesn't work on GNU/Hurd.
+ * doc/posix-functions/utimensat.texi: Mention the bug.
+
2025-03-13 Collin Funk <collin.funk1@gmail.com>
vma-iter: Detect executable memory segments on Haiku (regr. 2011-01-25).
@item
Out-of-range values of @code{tv_nsec} do not lead to a failure on some
platforms:
-Linux kernel 2.6.22.19 on hppa, NetBSD 10.0.
+@c https://sourceware.org/bugzilla/show_bug.cgi?id=32802
+Linux kernel 2.6.22.19 on hppa, NetBSD 10.0, GNU/Hurd.
@item
On some platforms, this function mis-handles a trailing slash:
AIX 7.2.
}
# endif
# endif
-# if defined __APPLE__ && defined __MACH__
- /* macOS 10.13 does not reject invalid tv_nsec values either. */
+# if (defined __APPLE__ && defined __MACH__) || defined __gnu_hurd__
+ /* macOS 10.13 and GNU Hurd do not reject invalid tv_nsec values
+ either. */
if (times
&& ((times[0].tv_nsec != UTIME_OMIT
&& times[0].tv_nsec != UTIME_NOW
errno = EINVAL;
return -1;
}
+# if defined __APPLE__ && defined __MACH__
size_t len = strlen (file);
if (len > 0 && file[len - 1] == '/')
{
return -1;
}
}
+# endif
# endif
result = utimensat (fd, file, times, flag);
/* Linux kernel 2.6.25 has a bug where it returns EINVAL for
# utimensat.m4
-# serial 12
+# serial 14
dnl Copyright (C) 2009-2025 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
ts[1].tv_sec = 1;
ts[1].tv_nsec = UTIME_OMIT;
if (utimensat (AT_FDCWD, f, ts, 0))
- result |= 16;
+ result |= 8;
if (stat (f, &st))
- result |= 32;
+ result |= 8;
else if (st.st_ctime < st.st_atime)
- result |= 64;
+ result |= 16;
+ }
+ enum
+ {
+ BILLION = 1000 * 1000 * 1000,
+ /* Bogus positive and negative tv_nsec values closest to valid
+ range, but without colliding with UTIME_NOW or UTIME_OMIT. */
+ UTIME_BOGUS_POS = BILLION + ((UTIME_NOW == BILLION || UTIME_OMIT == BILLION)
+ ? (1 + (UTIME_NOW == BILLION + 1)
+ + (UTIME_OMIT == BILLION + 1))
+ : 0)
+ };
+ {
+ struct timespec ts[2];
+ ts[0].tv_sec = 1;
+ ts[0].tv_nsec = UTIME_BOGUS_POS;
+ ts[1].tv_sec = 1;
+ ts[1].tv_nsec = 0;
+ if (utimensat (AT_FDCWD, f, ts, 0) == 0)
+ result |= 32;
}
return result;
]])],
],
[case "$host_os" in
# Guess yes on Linux or glibc systems.
- linux-* | linux | *-gnu* | gnu*)
+ linux*)
gl_cv_func_utimensat_works="guessing yes" ;;
+ # Guess no on GNU/Hurd.
+ gnu*)
+ gl_cv_func_utimensat_works="guessing no" ;;
# Guess yes on systems that emulate the Linux system calls.
midipix*)
gl_cv_func_utimensat_works="guessing yes" ;;