Mercurial > hg > octave-lyh > gnulib-hg
changeset 13782:3a4a1b81c846
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.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Fri, 08 Oct 2010 21:52:56 +0200 |
parents | e9b975e48d33 |
children | 47adc262f2b7 |
files | ChangeLog lib/nanosleep.c |
diffstat | 2 files changed, 45 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-10-08 Bruno Haible <bruno@clisp.org> + + 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. + 2010-10-08 Paul Eggert <eggert@cs.ucla.edu> bootstrap: add hook for altering gnulib.mk, for Bison
--- a/lib/nanosleep.c +++ b/lib/nanosleep.c @@ -50,38 +50,47 @@ /* 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; + by breaking the sleep up into smaller chunks. */ - while (limit < seconds) + if (requested_delay->tv_nsec < 0 || BILLION <= requested_delay->tv_nsec) { - 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; - } + errno = EINVAL; + return -1; } - intermediate.tv_sec = seconds; - intermediate.tv_nsec = requested_delay->tv_nsec; - return nanosleep (&intermediate, remaining_delay); + + { + /* 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__