summaryrefslogtreecommitdiffstats
path: root/lib/libc/gen/sleep.c
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>1997-08-13 18:13:17 +0000
committerache <ache@FreeBSD.org>1997-08-13 18:13:17 +0000
commit4dd0f70342485829d6d06bb4e7f169cce253438a (patch)
tree1496718463b48b8dea784fed27e9228251bfc905 /lib/libc/gen/sleep.c
parent17e05ba7e22711bea49b3d84e522c1355d55900c (diff)
downloadFreeBSD-src-4dd0f70342485829d6d06bb4e7f169cce253438a.zip
FreeBSD-src-4dd0f70342485829d6d06bb4e7f169cce253438a.tar.gz
Back out itimerfix hack since nanosleep1 fixed now
Handle syscalls error return slightly better
Diffstat (limited to 'lib/libc/gen/sleep.c')
-rw-r--r--lib/libc/gen/sleep.c77
1 files changed, 19 insertions, 58 deletions
diff --git a/lib/libc/gen/sleep.c b/lib/libc/gen/sleep.c
index 3405741..3904781 100644
--- a/lib/libc/gen/sleep.c
+++ b/lib/libc/gen/sleep.c
@@ -43,8 +43,6 @@ static char sccsid[] = "@(#)sleep.c 8.1 (Berkeley) 6/4/93";
#include "pthread_private.h"
#endif
-#define ITIMERMAX 100000000
-
#ifndef _THREAD_SAFE
static void
sleephandler()
@@ -58,41 +56,19 @@ sleep(seconds)
unsigned int seconds;
{
#ifdef _THREAD_SAFE
- unsigned int rest = 0;
struct timespec time_to_sleep;
struct timespec time_remaining;
if (seconds != 0) {
- again:
- /*
- * XXX
- * Hack to work around itimerfix(9) gratuitously limiting
- * the acceptable range for a struct timeval.tv_sec to
- * <= ITIMERMAX.
- */
- if (seconds > ITIMERMAX) {
- rest = seconds - ITIMERMAX;
- seconds = ITIMERMAX;
- }
time_to_sleep.tv_sec = seconds;
time_to_sleep.tv_nsec = 0;
- nanosleep(&time_to_sleep, &time_remaining);
-
- if (rest != 0 &&
- time_remaining.tv_sec == 0 &&
- time_remaining.tv_nsec == 0) {
- seconds = rest;
- rest = 0;
- goto again;
- }
-
- rest += time_remaining.tv_sec;
+ (void)nanosleep(&time_to_sleep, &time_remaining);
+ seconds = time_remaining.tv_sec;
if (time_remaining.tv_nsec > 0)
- rest++; /* round up */
+ seconds++; /* round up */
}
- return (rest);
+ return (seconds);
#else
- unsigned int rest = 0;
struct timespec time_to_sleep;
struct timespec time_remaining;
struct sigaction act, oact;
@@ -100,11 +76,14 @@ sleep(seconds)
int alarm_blocked;
if (seconds != 0) {
+ time_to_sleep.tv_sec = seconds;
+ time_to_sleep.tv_nsec = 0;
/* Block SIGALRM while fiddling with it */
sigemptyset(&mask);
sigaddset(&mask, SIGALRM);
- sigprocmask(SIG_BLOCK, &mask, &omask);
+ if (sigprocmask(SIG_BLOCK, &mask, &omask))
+ return (seconds);
/* Was SIGALRM blocked already? */
alarm_blocked = sigismember(&omask, SIGALRM);
@@ -116,23 +95,13 @@ sleep(seconds)
*/
memset(&act, 0, sizeof(act));
act.sa_handler = sleephandler;
- sigaction(SIGALRM, &act, &oact);
+ if (sigaction(SIGALRM, &act, &oact)) {
+ (void)sigprocmask(SIG_SETMASK, &omask,
+ (sigset_t *)0);
+ return (seconds);
+ }
}
- again:
- /*
- * XXX
- * Hack to work around itimerfix(9) gratuitously limiting
- * the acceptable range for a struct timeval.tv_sec to
- * <= ITIMERMAX
- */
- if (seconds > ITIMERMAX) {
- rest = seconds - ITIMERMAX;
- seconds = ITIMERMAX;
- }
- time_to_sleep.tv_sec = seconds;
- time_to_sleep.tv_nsec = 0;
-
/*
* signanosleep() uses the given mask for the lifetime of
* the syscall only - it resets on return. Note that the
@@ -141,27 +110,19 @@ sleep(seconds)
* to end the timeout. If the process blocks SIGALRM, it
* gets what it asks for.
*/
- signanosleep(&time_to_sleep, &time_remaining, &omask);
-
- if (rest != 0 &&
- time_remaining.tv_sec == 0 &&
- time_remaining.tv_nsec == 0) {
- seconds = rest;
- rest = 0;
- goto again;
- }
+ (void)signanosleep(&time_to_sleep, &time_remaining, &omask);
if (!alarm_blocked) {
/* Unwind */
- sigaction(SIGALRM, &oact, (struct sigaction *)0);
- sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0);
+ (void)sigaction(SIGALRM, &oact, (struct sigaction *)0);
+ (void)sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0);
}
/* return how long is left */
- rest += time_remaining.tv_sec;
+ seconds = time_remaining.tv_sec;
if (time_remaining.tv_nsec > 0)
- rest++; /* round up */
+ seconds++; /* round up */
}
- return (rest);
+ return (seconds);
#endif /* _THREAD_SAFE */
}
OpenPOWER on IntegriCloud