aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/unix/sysv/linux
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/unix/sysv/linux')
-rw-r--r--sysdeps/unix/sysv/linux/clock_settime.c58
1 files changed, 58 insertions, 0 deletions
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>