]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Y2038: add function __clock_settime64
authorAlbert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Thu, 7 Sep 2017 22:41:35 +0000 (00:41 +0200)
committerAlbert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Wed, 24 Oct 2018 10:53:27 +0000 (12:53 +0200)
* 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.

include/time.h
sysdeps/unix/clock_settime.c
sysdeps/unix/sysv/linux/clock_settime.c

index a8372fa0b632d6eab8221d51eef68a212ae88fe8..4db6cb17ce169f6f93aeca31282a45cb9ac73ba0 100644 (file)
@@ -42,6 +42,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;
index 38813eddf7b66ca1de8ec832f33abf5ccbc5de7f..13abe31023f7b1f699a38c3f4803ac5bd4adc747 100644 (file)
@@ -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)
 {
index 5f3f22f74b3e745c049d26fa2c031aaa94910762..5913dd69d5a2379297ad4d8605c941c9eb9e592a 100644 (file)
@@ -18,6 +18,7 @@
 #include <errno.h>
 #include <sysdep.h>
 #include <time.h>
+#include <y2038-support.h>
 
 #include "kernel-posix-cpu-timers.h"
 
 #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>