summaryrefslogtreecommitdiff
path: root/lib/xnanosleep.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2002-09-15 06:52:29 +0000
committerJim Meyering <jim@meyering.net>2002-09-15 06:52:29 +0000
commitec317bd993d9fe8958c5ff9305cfae2af397fc7e (patch)
treed158f96adf18186c7287a7fb8d77df0c0ef1389a /lib/xnanosleep.c
parent466902bf345ffc4afa464138212d41831ffe2e39 (diff)
downloadcoreutils-ec317bd993d9fe8958c5ff9305cfae2af397fc7e.tar.xz
(xnanosleep): Return -1 on failure, not 1, for consistency with nanosleep.
Check errno after nanosleep returns -1.
Diffstat (limited to 'lib/xnanosleep.c')
-rw-r--r--lib/xnanosleep.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/lib/xnanosleep.c b/lib/xnanosleep.c
index e6289fe68..8f9eb7e25 100644
--- a/lib/xnanosleep.c
+++ b/lib/xnanosleep.c
@@ -24,6 +24,7 @@
#include <stdio.h>
#include <assert.h>
+#include <errno.h>
#include <sys/types.h>
#include <time.h>
@@ -123,7 +124,8 @@ clock_get_realtime (struct timespec *ts)
SECONDS seconds after the time this function is called.
SECONDS must be non-negative. If SECONDS is so large that
it is not representable as a `struct timespec', then use
- the maximum value for that interval. */
+ the maximum value for that interval. Return -1 on failure
+ (setting errno), 0 on success. */
int
xnanosleep (double seconds)
@@ -147,7 +149,7 @@ xnanosleep (double seconds)
#endif
if (clock_get_realtime (&ts_start) == NULL)
- return 1;
+ return -1;
/* Separate whole seconds from nanoseconds.
Be careful to detect any overflow. */
@@ -193,13 +195,22 @@ xnanosleep (double seconds)
ts_sleep.tv_nsec = ts_stop.tv_nsec = 999999999;
}
- /* In case this process is suspended, then resumed, we'll know
- whether to resume sleeping. */
- while (nanosleep (&ts_sleep, NULL) != 0
- && timespec_subtract (&ts_sleep, &ts_stop,
- clock_get_realtime (&ts_start)))
+ while (nanosleep (&ts_sleep, NULL) != 0)
{
- continue;
+ if (errno != EINTR)
+ return -1;
+
+ /* POSIX.1-2001 requires that when a process is suspended, then
+ resumed, nanosleep (A, B) returns -1, sets errno to EINTR,
+ and sets *B to the time remaining at the point of resumption.
+ However, some versions of the Linux kernel incorrectly return
+ the time remaining at the point of suspension. Work around
+ this bug by computing the remaining time here, rather than by
+ relying on nanosleep's computation. */
+
+ if (! timespec_subtract (&ts_sleep, &ts_stop,
+ clock_get_realtime (&ts_start)))
+ break;
}
return 0;