This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH] Y2038: add function __clock_settime64
- From: "Albert ARIBAUD (3ADEV)" <albert dot aribaud at 3adev dot fr>
- To: libc-alpha at sourceware dot org
- Cc: "Albert ARIBAUD (3ADEV)" <albert dot aribaud at 3adev dot fr>
- Date: Wed, 19 Sep 2018 09:35:53 +0200
- Subject: [PATCH] Y2038: add function __clock_settime64
* include/time.h (__clock_settime64): Add.
* sysdeps/unix/clock_settime.c (__clock_settime64): Add.
* sysdeps/unix/sysv/linux/clock_settime.c (DO_CLOCK_SETTIME_32): Add.
* sysdeps/unix/sysv/linux/clock_settime.c (DO_CLOCK_SETTIME_64): Add.
* sysdeps/unix/sysv/linux/clock_settime.c (SYSDEP_SETTIME64_CPUTIME): Add.
* sysdeps/unix/sysv/linux/clock_settime.c (SYSDEP_SETTIME64): Add.
---
This patch is part of the Y2038 patch series, which is available at
<https://sourceware.org/git/?p=glibc.git;a=shortlog;h=refs/heads/aaribaud/y2038>.
Warning: this branch may be rebased on current master and/or updated based on
feedback from the list at any time.
include/time.h | 2 +
sysdeps/unix/clock_settime.c | 60 ++++++++++++++++++++++++-
sysdeps/unix/sysv/linux/clock_settime.c | 58 ++++++++++++++++++++++++
3 files changed, 119 insertions(+), 1 deletion(-)
diff --git a/include/time.h b/include/time.h
index 9efd153b83..5a658223ce 100644
--- a/include/time.h
+++ b/include/time.h
@@ -26,6 +26,8 @@ extern __typeof (clock_getcpuclockid) __clock_getcpuclockid;
extern int __clock_gettime64 (clockid_t __clock_id,
struct __timespec64 *__tp) __THROW;
+extern int __clock_settime64 (clockid_t __clock_id,
+ const struct __timespec64 *__tp) __THROW;
/* Now define the internal interfaces. */
struct tm;
diff --git a/sysdeps/unix/clock_settime.c b/sysdeps/unix/clock_settime.c
index 38813eddf7..13abe31023 100644
--- a/sysdeps/unix/clock_settime.c
+++ b/sysdeps/unix/clock_settime.c
@@ -68,8 +68,66 @@ hp_timing_settime (clockid_t clock_id, const struct timespec *tp)
}
#endif
-
/* Set CLOCK to value TP. */
+int
+__clock_settime64 (clockid_t clock_id, const struct __timespec64 *tp)
+{
+#ifndef HANDLED_REALTIME
+ struct timeval tv32;
+#endif
+ int retval = -1;
+
+ /* Make sure the time cvalue is OK. */
+ if (! IS_VALID_NANOSECONDS(tp->tv_nsec))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
+
+ switch (clock_id)
+ {
+#define HANDLE_REALTIME64 \
+ if (timespec64_to_timeval (tp, &tv32)) \
+ { \
+ retval = __settimeofday (&tv32, NULL); \
+ else \
+ { \
+ __set_errno (EOVERFLOW); \
+ retval = -1; \
+ }
+
+#ifdef SYSDEP_SETTIME64
+ SYSDEP_SETTIME64;
+#endif
+
+#ifndef HANDLED_REALTIME
+ case CLOCK_REALTIME:
+ HANDLE_REALTIME64;
+ break;
+#endif
+
+ default:
+#ifdef SYSDEP_SETTIME64_CPU
+ SYSDEP_SETTIME64_CPU;
+#endif
+#ifndef HANDLED_CPUTIME
+# if HP_TIMING_AVAIL
+ if (CPUCLOCK_WHICH (clock_id) == CLOCK_PROCESS_CPUTIME_ID
+ || CPUCLOCK_WHICH (clock_id) == CLOCK_THREAD_CPUTIME_ID)
+ retval = hp_timing_settime (clock_id, tp);
+ else
+# endif
+ {
+ __set_errno (EINVAL);
+ retval = -1;
+ }
+#endif
+ break;
+ }
+
+ return retval;
+}
+
int
__clock_settime (clockid_t clock_id, const struct timespec *tp)
{
diff --git a/sysdeps/unix/sysv/linux/clock_settime.c b/sysdeps/unix/sysv/linux/clock_settime.c
index 5f3f22f74b..5913dd69d5 100644
--- a/sysdeps/unix/sysv/linux/clock_settime.c
+++ b/sysdeps/unix/sysv/linux/clock_settime.c
@@ -18,6 +18,7 @@
#include <errno.h>
#include <sysdep.h>
#include <time.h>
+#include <y2038-support.h>
#include "kernel-posix-cpu-timers.h"
@@ -35,4 +36,61 @@
#define SYSDEP_SETTIME_CPU \
retval = INLINE_SYSCALL (clock_settime, 2, clock_id, tp)
+/* 64-bit time version */
+
+# define DO_CLOCK_SETTIME_32 \
+ if (! fits_in_time_t(tp->tv_sec)) \
+ { \
+ __set_errno (EOVERFLOW); \
+ retval = -1; \
+ } \
+ else \
+ { \
+ valid_timespec64_to_timespec(tp, &ts32); \
+ retval = INLINE_SYSCALL (clock_settime, 2, clock_id, &ts32); \
+ }
+
+#ifdef __NR_clock_settime64
+
+/* We are building with a 64-bit-time clock_gettime syscall */
+
+# define DO_CLOCK_SETTIME_64 \
+ if (__y2038_linux_support > 0) \
+ { \
+ ts64.tv_sec = tp->tv_sec; \
+ ts64.tv_nsec = tp->tv_nsec; \
+ ts64.tv_pad = 0; \
+ retval = INLINE_SYSCALL (clock_settime64, 2, clock_id, &ts64); \
+ if (retval == 1 && errno==ENOSYS) \
+ { \
+ __y2038_linux_support = -1; \
+ DO_CLOCK_SETTIME_32; \
+ } \
+ } \
+ else \
+ { \
+ DO_CLOCK_SETTIME_32; \
+ }
+
+# define SYSDEP_SETTIME64_CPUTIME \
+ struct __timespec64 ts64; \
+ struct timespec ts32
+
+#else
+
+/* We are building without a 64-bit-time clock_gettime syscall */
+
+# define DO_CLOCK_SETTIME_64 DO_CLOCK_SETTIME_32
+
+# define SYSDEP_SETTIME64_CPUTIME \
+ struct timespec ts32
+
+#endif
+
+#define SYSDEP_SETTIME64 \
+ SYSDEP_SETTIME64_CPUTIME; \
+ case CLOCK_REALTIME: \
+ DO_CLOCK_SETTIME_64; \
+ break
+
#include <sysdeps/unix/clock_settime.c>
--
2.17.1