[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: OpenBSD 4.7 vs nanosleep
From: |
Bruno Haible |
Subject: |
Re: OpenBSD 4.7 vs nanosleep |
Date: |
Fri, 8 Oct 2010 21:55:09 +0200 |
User-agent: |
KMail/1.9.9 |
Hi Jim,
> This isn't a show-stopper for the coreutils release.
But it's easy to fix. The bug is actually in the gnulib replacement, which
is missing a check on the validity of the argument.
2010-10-08 Bruno Haible <address@hidden>
nanosleep: Make replacement POSIX compliant.
* lib/nanosleep.c (nanosleep): Return -1/EINVAL if the delay's tv_nsec
is out of range.
Reported by Jim Meyering.
*** lib/nanosleep.c.orig Fri Oct 8 21:50:25 2010
--- lib/nanosleep.c Fri Oct 8 21:49:56 2010
***************
*** 50,87 ****
/* nanosleep mishandles large sleeps due to internal overflow
problems. The worst known case of this is cygwin 1.5.x, which
can't sleep more than 49.7 days (2**32 milliseconds). Solve this
! by breaking the sleep up into smaller chunks. Verify that time_t
! is large enough. */
! verify (TYPE_MAXIMUM (time_t) / 49 / 24 / 60 / 60);
! const time_t limit = 49 * 24 * 60 * 60;
! time_t seconds = requested_delay->tv_sec;
! struct timespec intermediate;
! intermediate.tv_nsec = 0;
! while (limit < seconds)
{
! int result;
! intermediate.tv_sec = limit;
! result = nanosleep (&intermediate, remaining_delay);
! seconds -= limit;
! if (result)
! {
! if (remaining_delay)
! {
! remaining_delay->tv_sec += seconds;
! remaining_delay->tv_nsec += requested_delay->tv_nsec;
! if (BILLION <= requested_delay->tv_nsec)
! {
! remaining_delay->tv_sec++;
! remaining_delay->tv_nsec -= BILLION;
! }
! }
! return result;
! }
}
! intermediate.tv_sec = seconds;
! intermediate.tv_nsec = requested_delay->tv_nsec;
! return nanosleep (&intermediate, remaining_delay);
}
#elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
--- 50,96 ----
/* nanosleep mishandles large sleeps due to internal overflow
problems. The worst known case of this is cygwin 1.5.x, which
can't sleep more than 49.7 days (2**32 milliseconds). Solve this
! by breaking the sleep up into smaller chunks. */
! if (requested_delay->tv_nsec < 0 || BILLION <= requested_delay->tv_nsec)
{
! errno = EINVAL;
! return -1;
}
!
! {
! /* Verify that time_t is large enough. */
! verify (TYPE_MAXIMUM (time_t) / 49 / 24 / 60 / 60);
! const time_t limit = 49 * 24 * 60 * 60;
! time_t seconds = requested_delay->tv_sec;
! struct timespec intermediate;
! intermediate.tv_nsec = 0;
!
! while (limit < seconds)
! {
! int result;
! intermediate.tv_sec = limit;
! result = nanosleep (&intermediate, remaining_delay);
! seconds -= limit;
! if (result)
! {
! if (remaining_delay)
! {
! remaining_delay->tv_sec += seconds;
! remaining_delay->tv_nsec += requested_delay->tv_nsec;
! if (BILLION <= requested_delay->tv_nsec)
! {
! remaining_delay->tv_sec++;
! remaining_delay->tv_nsec -= BILLION;
! }
! }
! return result;
! }
! }
! intermediate.tv_sec = seconds;
! intermediate.tv_nsec = requested_delay->tv_nsec;
! return nanosleep (&intermediate, remaining_delay);
! }
}
#elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__