diff options
author | joseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2012-05-12 15:44:41 +0000 |
---|---|---|
committer | joseph <joseph@7b3dc134-2b1b-0410-93df-9e9f96275f8d> | 2012-05-12 15:44:41 +0000 |
commit | 62eb53f68d92687a028f3c515489b30e3df1d979 (patch) | |
tree | 7fcf1c95d89caecbbff5d932778f04670c151c52 /libc/sysdeps/mach/nanosleep.c | |
parent | c29b18b38ccefba22c13b33dd801acba0ae92523 (diff) | |
download | eglibc2-62eb53f68d92687a028f3c515489b30e3df1d979.tar.gz |
Merge changes between r18392 and r18519 from /fsf/trunk.
git-svn-id: svn://svn.eglibc.org/trunk@18520 7b3dc134-2b1b-0410-93df-9e9f96275f8d
Diffstat (limited to 'libc/sysdeps/mach/nanosleep.c')
-rw-r--r-- | libc/sysdeps/mach/nanosleep.c | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/libc/sysdeps/mach/nanosleep.c b/libc/sysdeps/mach/nanosleep.c index 0192ff0bd..a1ba19c17 100644 --- a/libc/sysdeps/mach/nanosleep.c +++ b/libc/sysdeps/mach/nanosleep.c @@ -1,5 +1,5 @@ /* nanosleep -- sleep for a period specified with a struct timespec - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002-2012 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -27,6 +27,15 @@ __nanosleep (const struct timespec *requested_time, { mach_port_t recv; struct timeval before, after; + + if (requested_time->tv_sec < 0 + || requested_time->tv_nsec < 0 + || requested_time->tv_nsec >= 1000000000) + { + errno = EINVAL; + return -1; + } + const mach_msg_timeout_t ms = requested_time->tv_sec * 1000 + (requested_time->tv_nsec + 999999) / 1000000; @@ -35,16 +44,22 @@ __nanosleep (const struct timespec *requested_time, if (remaining && __gettimeofday (&before, NULL) < 0) return -1; - (void) __mach_msg (NULL, MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT, - 0, 0, recv, ms, MACH_PORT_NULL); + error_t err = __mach_msg (NULL, MACH_RCV_MSG|MACH_RCV_TIMEOUT|MACH_RCV_INTERRUPT, + 0, 0, recv, ms, MACH_PORT_NULL); __mach_port_destroy (mach_task_self (), recv); - if (remaining && __gettimeofday (&after, NULL) < 0) - return -1; - - if (remaining) + if (err == EMACH_RCV_INTERRUPTED) { - timersub (&after, &before, &after); - TIMEVAL_TO_TIMESPEC (&after, remaining); + if (remaining && __gettimeofday (&after, NULL) >= 0) + { + struct timeval req_time, elapsed, rem; + TIMESPEC_TO_TIMEVAL (&req_time, requested_time); + timersub (&after, &before, &elapsed); + timersub (&req_time, &elapsed, &rem); + TIMEVAL_TO_TIMESPEC (&rem, remaining); + } + + errno = EINTR; + return -1; } return 0; |