From 73fd69180b8c4cee3505224dd4b76f7cf292495d Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 4 Sep 2022 13:26:19 +0200 Subject: [PATCH] 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. --- ChangeLog | 7 +++++++ doc/posix-functions/nanosleep.texi | 4 ++++ m4/nanosleep.m4 | 17 ++++++++++++----- tests/test-nanosleep.c | 11 +++++++++++ 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index b56dab9b08..79c81fd113 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2022-09-04 Bruno Haible + + 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 fmal: Work around glibc 2.17 bug on x86_64. diff --git a/doc/posix-functions/nanosleep.texi b/doc/posix-functions/nanosleep.texi index 8ede0b01f9..be54aef571 100644 --- a/doc/posix-functions/nanosleep.texi +++ b/doc/posix-functions/nanosleep.texi @@ -18,6 +18,10 @@ Linux 64-bit, Solaris 64-bit. @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: diff --git a/m4/nanosleep.m4 b/m4/nanosleep.m4 index 1964b1ea47..dfe21f56d5 100644 --- a/m4/nanosleep.m4 +++ b/m4/nanosleep.m4 @@ -1,4 +1,4 @@ -# serial 41 +# serial 42 dnl From Jim Meyering. dnl Check for the nanosleep function. @@ -100,15 +100,22 @@ AC_DEFUN([gl_FUNC_NANOSLEEP], #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. diff --git a/tests/test-nanosleep.c b/tests/test-nanosleep.c index e7edeffc0e..c208161559 100644 --- a/tests/test-nanosleep.c +++ b/tests/test-nanosleep.c @@ -43,16 +43,27 @@ main (void) { 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); -- 2.39.5