* m4/nanosleep.m4 (gl_FUNC_NANOSLEEP): Test for 32-bit mingw bug.
* tests/test-nanosleep.c (main): Add another test.
* doc/posix-functions/nanosleep.texi: Mention the mingw bug.
+2022-09-04 Bruno Haible <bruno@clisp.org>
+
+ nanosleep: Work around bug on newer 32-bit mingw.
+ * m4/nanosleep.m4 (gl_FUNC_NANOSLEEP): Test for 32-bit mingw bug.
+ * tests/test-nanosleep.c (main): Add another test.
+ * doc/posix-functions/nanosleep.texi: Mention the mingw bug.
+
2022-09-03 Bruno Haible <bruno@clisp.org>
fmal: Work around glibc 2.17 bug on x86_64.
@item
This function cannot sleep longer than 49.7 days on some platforms:
Cygwin 1.5.x.
+@item
+This function does not fail when passed a negative nanosecond value on some
+platforms:
+newer 32-bit mingw.
@end itemize
Portability problems not fixed by Gnulib:
-# serial 41
+# serial 42
dnl From Jim Meyering.
dnl Check for the nanosleep function.
#else /* A simpler test for native Windows. */
if (nanosleep (&ts_sleep, &ts_remaining) < 0)
return 3;
+ /* Test for 32-bit mingw bug: negative nanosecond values do not
+ cause failure. */
+ ts_sleep.tv_sec = 1;
+ ts_sleep.tv_nsec = -1;
+ if (nanosleep (&ts_sleep, &ts_remaining) != -1)
+ return 7;
#endif
return 0;
}]])],
[gl_cv_func_nanosleep=yes],
- [case $? in dnl (
- 4|5|6) gl_cv_func_nanosleep='no (mishandles large arguments)';; dnl (
- *) gl_cv_func_nanosleep=no;;
+ [case $? in
+ 4|5|6) gl_cv_func_nanosleep='no (mishandles large arguments)' ;;
+ 7) gl_cv_func_nanosleep='no (mishandles negative tv_nsec)' ;;
+ *) gl_cv_func_nanosleep=no ;;
esac],
- [case "$host_os" in dnl ((
+ [case "$host_os" in
linux*) # Guess it halfway works when the kernel is Linux.
gl_cv_func_nanosleep='guessing no (mishandles large arguments)' ;;
mingw*) # Guess no on native Windows.
{
struct timespec ts;
+ /* Check that negative nanosecond values cause failure. */
+ ts.tv_sec = 1;
+ ts.tv_nsec = -1;
+ errno = 0;
+ ASSERT (nanosleep (&ts, NULL) == -1);
+ ASSERT (errno == EINVAL);
+
ts.tv_sec = 1000;
ts.tv_nsec = -1;
errno = 0;
ASSERT (nanosleep (&ts, NULL) == -1);
ASSERT (errno == EINVAL);
+
+ /* Check that too large nanosecond values cause failure. */
+ ts.tv_sec = 1000;
ts.tv_nsec = 1000000000;
errno = 0;
ASSERT (nanosleep (&ts, NULL) == -1);
ASSERT (errno == EINVAL);
+ /* Check successful call. */
ts.tv_sec = 0;
ts.tv_nsec = 1;
ASSERT (nanosleep (&ts, &ts) == 0);