]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Y2038: add function __clock_nanosleep64
authorAlbert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Thu, 7 Sep 2017 22:41:37 +0000 (00:41 +0200)
committerAlbert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Wed, 24 Oct 2018 10:53:27 +0000 (12:53 +0200)
Linux does not provide a 64-bit-time clock_nanosleep syscall,
so __clock_nanosleep64 is a wrapper calling __clock_nanosleep,
with one conversion before the call and possibly one after.

Note:

There is no point in implementing __clock_nanosleep64 directly
around the 32-bit-time syscall and making __clock_nanosleep a
wrapper around __clock_nanosleep64, because __clock_nanosleep64
would still need one or two conversions, and __clock_nanosleep
would now also need those, adding a cost of 2 to 4 conversions
in the worst case.

include/time.h
sysdeps/unix/sysv/linux/clock_nanosleep.c
time/Versions

index f24ae1992d8decad976d7f0dd3ebe400053ead6e..2bfba396fe8eb8f6e04f56c71156014771ee80d1 100644 (file)
@@ -46,6 +46,9 @@ extern int __clock_settime64 (clockid_t __clock_id,
                               const struct __timespec64 *__tp) __THROW;
 extern int __clock_getres_time64 (clockid_t __clock_id,
                                  struct __timespec64 *__res) __THROW;
+extern int __clock_nanosleep64 (clockid_t __clock_id, int __flags,
+                               const struct __timespec64 *__req,
+                               struct __timespec64 *__rem);
 
 /* Now define the internal interfaces.  */
 struct tm;
index 93d5d6ef120ca9ef6b14f0e4b2916e172d56c676..6878da90654e8b2b781f6ba80088d6da1759cabf 100644 (file)
@@ -21,7 +21,6 @@
 #include <sysdep-cancel.h>
 #include "kernel-posix-cpu-timers.h"
 
-
 /* We can simply use the syscall.  The CPU clocks are not supported
    with this function.  */
 int
@@ -52,3 +51,51 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req,
          ? INTERNAL_SYSCALL_ERRNO (r, err) : 0);
 }
 weak_alias (__clock_nanosleep, clock_nanosleep)
+
+/* 64-bit time version */
+
+/* We don't have a 64-bit-time syscall yet, so just convert arguments
+ * between 64-bit and 32-bit time, and use the 32-bit implementation.
+ * 
+ * We could do the reverse and make the 32-bit time implementation a
+ * wrapper around the 64-bit-time implementation, but then 32-bit-time
+ * uses would incur four conversions instead of zero right now.
+ */
+int
+__clock_nanosleep64 (clockid_t clock_id, int flags,
+                    const struct __timespec64 *req,
+                    struct __timespec64 *rem)
+{
+  int res;
+  struct timespec req32, rem32, *rem32p = NULL;
+
+  if (req == NULL)
+    {
+      __set_errno (EFAULT);
+      return -1;
+    }
+
+  if (req->tv_sec > INT32_MAX || req->tv_sec < INT32_MIN)
+    {
+      __set_errno (EOVERFLOW);
+      return -1;
+    }
+
+  /* For now, use the 32-bit-time implementation above */
+
+  req32.tv_sec = req->tv_sec;
+  req32.tv_nsec = req->tv_nsec;
+
+  if (rem != NULL)
+    rem32p = &rem32;
+
+  res = __clock_nanosleep (clock_id, flags, &req32, rem32p);
+
+  if (res == 0 && rem != NULL)
+    {
+      rem->tv_sec = rem32.tv_sec;
+      rem->tv_nsec = rem32.tv_nsec;
+    }
+
+  return res;
+}
index fd838181e4f0969dbd9a553d0378a7e8d4a90eff..5dfe98440a9849830195dbf020bf5a459bb459f7 100644 (file)
@@ -65,4 +65,14 @@ libc {
   GLIBC_2.16 {
     timespec_get;
   }
+  GLIBC_2.29 {
+    __ctime64; __ctime64_r;
+    __gmtime64; __gmtime64_r;
+    __localtime64; __localtime64_r;
+    __mktime64; __timelocal64_r; __timegm64;
+    __clock_gettime64;
+    __clock_settime64;
+    __clock_getres_time64;
+    __clock_nanosleep64;
+  }
 }