]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Y2038: add function __timer_settime64
authorAlbert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Thu, 7 Sep 2017 22:41:47 +0000 (00:41 +0200)
committerAlbert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Wed, 24 Oct 2018 10:53:27 +0000 (12:53 +0200)
For Linux this uses a 32-bit syscall, so it converts the syscall
input from 64-bit time into 32-bit time, and the syscall output
from 32-bit time into 64-bit time.

rt/Versions
sysdeps/unix/sysv/linux/arm/librt.abilist
sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
sysdeps/unix/sysv/linux/timer_settime.c

index e55faa062901cf81796db3ea46b3f0466d91adfa..c8703cbede067f68d07a0cb3f484ee3c2349f815 100644 (file)
@@ -39,5 +39,6 @@ librt {
   }
   GLIBC_2.29 {
    __timer_gettime64;
+   __timer_settime64;
   }
 }
index e18f5ee3f5c43f45ae1df3c71f4ca587d16c567e..b92173e1a910b24995a591308b547f5301fbfe9b 100644 (file)
@@ -1,4 +1,5 @@
 GLIBC_2.29 __timer_gettime64 F
+GLIBC_2.29 __timer_settime64 F
 GLIBC_2.4 aio_cancel F
 GLIBC_2.4 aio_cancel64 F
 GLIBC_2.4 aio_error F
index cb6ba7248ebdbbf50dffb89babe0252a8b1d26ec..e7774eedd458e21271aa24f8454e8086ca0c9f51 100644 (file)
@@ -28,6 +28,7 @@ GLIBC_2.2 timer_getoverrun F
 GLIBC_2.2 timer_gettime F
 GLIBC_2.2 timer_settime F
 GLIBC_2.29 __timer_gettime64 F
+GLIBC_2.29 __timer_settime64 F
 GLIBC_2.3.4 mq_close F
 GLIBC_2.3.4 mq_getattr F
 GLIBC_2.3.4 mq_notify F
index 7c938bd4a42b9d5ee9d8226f6f10e2e4301b0160..bc876a9e64b7bfed0f2b4d5e247f25c40d89ea23 100644 (file)
@@ -20,6 +20,7 @@
 #include <stdlib.h>
 #include <time.h>
 #include <sysdep.h>
+#include <y2038-support.h>
 #include "kernel-posix-timers.h"
 
 
@@ -41,3 +42,52 @@ timer_settime (timer_t timerid, int flags, const struct itimerspec *value,
 
   return res;
 }
+
+/* 64-bit time version */
+
+int
+__timer_settime64 (timer_t timerid, int flags, const struct itimerspec *value,
+                   struct itimerspec *ovalue)
+{
+  int res;
+  struct timer *kt = (struct timer *) timerid;
+  struct itimerspec value32, ovalue32;
+
+  if (value == NULL)
+  {
+    __set_errno(EFAULT);
+    return -1;
+  }
+
+#ifdef __NR_timer_settime64
+  if (__y2038_get_kernel_support () > 0)
+    {
+      res = INLINE_SYSCALL (timer_settime, 3, kt->ktimerid, value, ovalue);
+      if (res == 0 || errno != ENOSYS)
+        return res;
+      __y2038_set_kernel_support (-1);
+    }
+#endif
+
+  if (value->it_value.tv_sec > INT_MAX
+      || value->it_interval.tv_sec > INT_MAX)
+    return EOVERFLOW;
+
+  value32.it_value.tv_sec = value->it_value.tv_sec;
+  value32.it_value.tv_nsec = value->it_value.tv_nsec;
+  value32.it_interval.tv_sec = value->it_interval.tv_sec;
+  value32.it_interval.tv_nsec = value->it_interval.tv_nsec;
+
+  res = INLINE_SYSCALL (timer_settime, 4, kt->ktimerid, flags,
+        &value32, &ovalue32);
+
+  if (res == 0 && ovalue != NULL)
+    {
+      ovalue->it_value.tv_sec = ovalue32.it_value.tv_sec;
+      ovalue->it_value.tv_nsec = ovalue32.it_value.tv_nsec;
+      ovalue->it_interval.tv_sec = ovalue32.it_interval.tv_sec;
+      ovalue->it_interval.tv_nsec = ovalue32.it_interval.tv_nsec;
+    }
+
+  return res;
+}