diff options
author | dillon <dillon@FreeBSD.org> | 1998-09-06 09:11:06 +0000 |
---|---|---|
committer | dillon <dillon@FreeBSD.org> | 1998-09-06 09:11:06 +0000 |
commit | ac6dbb3f6993d2bab6c1c9d6ee2e366ec46b10cd (patch) | |
tree | d0df79d9eb233649c5625eec85754fc65c4f81a4 | |
parent | 83329c27b739f7f2e5af9f66f5852d72a0a8b6a3 (diff) | |
download | FreeBSD-src-ac6dbb3f6993d2bab6c1c9d6ee2e366ec46b10cd.zip FreeBSD-src-ac6dbb3f6993d2bab6c1c9d6ee2e366ec46b10cd.tar.gz |
Reviewed by: Andrey A. Chernov <ache@nagual.pp.ru>, Doug Rabson <dfr@nlsystems.com>
Rewrote sleep() to remove int/long typing assumptions between the argument
to the function and the timespec structure.
-rw-r--r-- | lib/libc/gen/sleep.c | 46 |
1 files changed, 29 insertions, 17 deletions
diff --git a/lib/libc/gen/sleep.c b/lib/libc/gen/sleep.c index 898ff1c..90ed333 100644 --- a/lib/libc/gen/sleep.c +++ b/lib/libc/gen/sleep.c @@ -36,7 +36,7 @@ static char sccsid[] = "@(#)sleep.c 8.1 (Berkeley) 6/4/93"; #endif static char rcsid[] = - "$Id: sleep.c,v 1.22 1997/10/17 09:35:50 ache Exp $"; + "$Id: sleep.c,v 1.23 1998/09/05 08:01:26 jb Exp $"; #endif /* LIBC_SCCS and not lint */ #include <errno.h> @@ -44,26 +44,38 @@ static char rcsid[] = #include <time.h> #include <unistd.h> +/* + * sleep() - attempt to sleep the specified number of seconds, returning + * any remaining unslept time if interrupted or 0 if the entire + * sleep completes without being interrupted. Avoid seconds vs + * time_t typing problems by breaking down large times with a + * loop. + */ + unsigned int sleep(seconds) unsigned int seconds; { - struct timespec time_to_sleep; - struct timespec time_remaining; + while (seconds != 0) { + struct timespec time_to_sleep; + struct timespec time_remaining; - /* - * Avoid overflow when `seconds' is huge. This assumes that - * the maximum value for a time_t is >= INT_MAX. - */ - if (seconds > INT_MAX) - return (seconds - INT_MAX + sleep(INT_MAX)); + time_to_sleep.tv_sec = (seconds > INT_MAX) ? INT_MAX : seconds; + time_to_sleep.tv_nsec = 0; - time_to_sleep.tv_sec = seconds; - time_to_sleep.tv_nsec = 0; - if (nanosleep(&time_to_sleep, &time_remaining) != -1) - return (0); - if (errno != EINTR) - return (seconds); /* best guess */ - return (time_remaining.tv_sec + - (time_remaining.tv_nsec != 0)); /* round up */ + if (nanosleep(&time_to_sleep, &time_remaining) == -1) { + /* + * time_remaining only valid if EINTR, else assume no + * time elapsed. + */ + if (errno == EINTR) + seconds -= time_to_sleep.tv_sec - time_remaining.tv_sec; + if (time_remaining.tv_nsec) + ++seconds; + break; + } + seconds -= time_to_sleep.tv_sec; + } + return(seconds); } + |