summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlbert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>2017-09-08 00:41:47 +0200
committerAlbert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>2018-04-11 22:39:44 +0200
commit4900169e18b615126db4d2f21988e17dd5e6f676 (patch)
tree0894ed714dd5bb931e7640e31062129d3d49dfdd
parentdb9e418a1a6f6c87461b2352bfa2d1814fff815f (diff)
downloadglibc-4900169e18b615126db4d2f21988e17dd5e6f676.tar.gz
Y2038: add function __timer_settime64
-rw-r--r--rt/Versions1
-rw-r--r--sysdeps/unix/sysv/linux/arm/librt.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/librt.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/timer_settime.c61
4 files changed, 64 insertions, 0 deletions
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..7014973945 100644
--- a/sysdeps/unix/sysv/linux/timer_settime.c
+++ b/sysdeps/unix/sysv/linux/timer_settime.c
@@ -41,3 +41,64 @@ 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;
+/* Only try and use this syscall if defined by kernel */
+#ifdef __NR_timer_settime64
+ struct __itimerspec64 value64;
+#endif
+
+ if (value == NULL)
+ {
+ __set_errno(EFAULT);
+ return -1;
+ }
+
+/* Only try and use this syscall if defined by kernel */
+#ifdef __NR_timer_settime64
+ if (__y2038_kernel_support())
+ {
+ value64.it_value.tv_sec = value->it_value.tv_sec;
+ value64.it_value.tv_nsec = value->it_value.tv_nsec;
+ value64.it_value.tv_pad = 0;
+ value64.it_interval.tv_sec = value->it_interval.tv_sec;
+ value64.it_interval.tv_nsec = value->it_interval.tv_nsec;
+ value64.it_interval.tv_pad = 0;
+
+ res = INLINE_SYSCALL (timer_settime64, 4, kt->ktimerid, flags,
+ &value64, ovalue);
+ if (res == 0 || errno != ENOSYS)
+ return res;
+ }
+#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;
+}