This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH,HURD] mach: compliance fixes for nanosleep


Hi,

attached there is a patch to make Mach's nanosleep() (used by Hurd) a 
bit more POSIX compliant:
* check for validity of the `requested_time' parameter
* return EINTR when interrupted
* modify correctly the `remaining' parameter only when interrupted

Thanks,
-- 
Pino Toscano
mach: compliance fixes for nanosleep

Make the nanosleep Mach implementation behave a bit more POSIX compliant:
* check for invalid values of the `requested_time' parameter
* check for an interrupted __mach_msg call, and only in that case modify
`remaining' with the remaining time (correctly calculated, as before it was
set to the elapsed time); fail with EINTR in this case

2012-04-28  Pino Toscano  <toscano.pino@tiscali.it>

	* sysdeps/mach/nanosleep.c: Return EINVAL for invalid values of
	`requested_time'.  Properly set the remaining time and return EINTR
	if interrupted.
--- a/sysdeps/mach/nanosleep.c
+++ b/sysdeps/mach/nanosleep.c
@@ -27,24 +27,38 @@ __nanosleep (const struct timespec *requ
 {
   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;
-
   recv = __mach_reply_port ();
 
   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;

Attachment: signature.asc
Description: This is a digitally signed message part.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]