diff mbox

[[PATCH,RFC,2] 28/63] Y2038: add function __timer_settime64

Message ID 20180418201819.15952-29-albert.aribaud@3adev.fr
State New
Headers show

Commit Message

Albert ARIBAUD April 18, 2018, 8:17 p.m. UTC
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                                        |  1 +
 sysdeps/unix/sysv/linux/arm/librt.abilist          |  1 +
 .../sysv/linux/powerpc/powerpc32/librt.abilist     |  1 +
 sysdeps/unix/sysv/linux/timer_settime.c            | 39 ++++++++++++++++++++++
 4 files changed, 42 insertions(+)
diff mbox

Patch

diff --git a/rt/Versions b/rt/Versions
index 8fcfba84fe..181e5e16ad 100644
--- a/rt/Versions
+++ b/rt/Versions
@@ -39,5 +39,6 @@  librt {
   }
   GLIBC_2.27 {
    __timer_gettime64;
+   __timer_settime64;
   }
 }
diff --git a/sysdeps/unix/sysv/linux/arm/librt.abilist b/sysdeps/unix/sysv/linux/arm/librt.abilist
index f942d47058..d76ec99c0a 100644
--- a/sysdeps/unix/sysv/linux/arm/librt.abilist
+++ b/sysdeps/unix/sysv/linux/arm/librt.abilist
@@ -1,5 +1,6 @@ 
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 __timer_gettime64 F
+GLIBC_2.27 __timer_settime64 F
 GLIBC_2.4 GLIBC_2.4 A
 GLIBC_2.4 aio_cancel F
 GLIBC_2.4 aio_cancel64 F
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
index 519a6f7657..cd7b5f1b97 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist
@@ -31,6 +31,7 @@  GLIBC_2.2 timer_gettime F
 GLIBC_2.2 timer_settime F
 GLIBC_2.27 GLIBC_2.27 A
 GLIBC_2.27 __timer_gettime64 F
+GLIBC_2.27 __timer_settime64 F
 GLIBC_2.3.4 GLIBC_2.3.4 A
 GLIBC_2.3.4 mq_close F
 GLIBC_2.3.4 mq_getattr F
diff --git a/sysdeps/unix/sysv/linux/timer_settime.c b/sysdeps/unix/sysv/linux/timer_settime.c
index 7c938bd4a4..653cca2c55 100644
--- a/sysdeps/unix/sysv/linux/timer_settime.c
+++ b/sysdeps/unix/sysv/linux/timer_settime.c
@@ -41,3 +41,42 @@  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;
+  }
+
+  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;
+}