]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Y2038: add function __clock_gettime64
authorAlbert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Sun, 8 Apr 2018 09:15:24 +0000 (11:15 +0200)
committerAlbert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr>
Wed, 24 Oct 2018 10:53:27 +0000 (12:53 +0200)
* include/time.h: Declare __clock_gettime64().
* ntpl/pthread_clock_gettime.c: Add __pthread_clock_gettime64().
* ntpl/pthread_clock_gettime.c: Make __pthread_clock_gettime()
  a wrapper around __pthread_clock_gettime64().
* sysdeps/unix/clock_gettime.c (hp_timing_gettime): Use struct
  __timespec64.
* sysdeps/unix/clock_gettime.c (realtime_gettime): Likewise.
* sysdeps/unix/clock_gettime.c: Add __clock_gettime64().
* sysdeps/unix/clock_gettime.c: Make __clock_gettime() a
  wrapper around __clock_gettime64().
* sysdeps/unix/sysv/linux/clock_gettime.c: Add 64-bit-time syscall
  support.

include/time.h
nptl/pthread_clock_gettime.c
sysdeps/unix/clock_gettime.c
sysdeps/unix/sysv/linux/clock_gettime.c

index f95f16ed46410af6f1eaff5882a061730bbc7550..a8372fa0b632d6eab8221d51eef68a212ae88fe8 100644 (file)
@@ -40,6 +40,9 @@ extern __typeof (clock_settime) __clock_settime;
 extern __typeof (clock_nanosleep) __clock_nanosleep;
 extern __typeof (clock_getcpuclockid) __clock_getcpuclockid;
 
+extern int __clock_gettime64 (clockid_t __clock_id,
+                             struct __timespec64 *__tp) __THROW;
+
 /* Now define the internal interfaces.  */
 struct tm;
 
index 6bc75cfe3f1ff8567ffd2cf56776aee9ed0c3038..508821b878bc14fbedb22f5f8dcbd2fc456de236 100644 (file)
 #include <errno.h>
 #include <stdlib.h>
 #include <time.h>
+#include <bits/types/struct_timespec64.h>
 #include "pthreadP.h"
 
 
 #if HP_TIMING_AVAIL
 int
-__pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq,
-                        struct timespec *tp)
+__pthread_clock_gettime64 (clockid_t clock_id, hp_timing_t freq,
+                          struct __timespec64 *tp)
 {
   hp_timing_t tsc;
 
@@ -64,4 +65,36 @@ __pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq,
 
   return 0;
 }
+
+int
+__pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq,
+                          struct timespec *tp)
+{
+  struct __timespec64 ts64;
+  int res;
+
+  if (tp == NULL)
+    {
+      __set_errno(EINVAL);
+      res = -1;
+    }
+  else
+    {
+      int res = __pthread_clock_gettime64 (clock_id, freq, &ts64);
+      if (res == 0)
+       {
+         if (fits_in_time_t (ts64.tv_time))
+           {
+             tp->tv_sec = ts64.tv_sec;
+             tp->tv_nsec = ts64.tv_nsec;
+           }
+         else
+           {
+             set_errno(EOVERFLOW);
+             res = -1;
+           }
+       }
+    }
+  return res;
+}
 #endif
index 96df78ab1ed09c042ac755ca05c7ee85cced8d68..88c1955f173d8f4d5d9384677c80c52d4dcb528e 100644 (file)
@@ -32,12 +32,12 @@ static hp_timing_t freq;
 
 
 /* This function is defined in the thread library.  */
-extern int __pthread_clock_gettime (clockid_t clock_id, hp_timing_t freq,
-                                   struct timespec *tp)
+extern int __pthread_clock_gettime64 (clockid_t clock_id, hp_timing_t freq,
+                                     struct __timespec64 *tp)
      __attribute__ ((__weak__));
 
 static int
-hp_timing_gettime (clockid_t clock_id, struct timespec *tp)
+hp_timing_gettime (clockid_t clock_id, struct __timespec64 *tp)
 {
   hp_timing_t tsc;
 
@@ -55,7 +55,7 @@ hp_timing_gettime (clockid_t clock_id, struct timespec *tp)
 
   if (clock_id != CLOCK_PROCESS_CPUTIME_ID
       && __pthread_clock_gettime != NULL)
-    return __pthread_clock_gettime (clock_id, freq, tp);
+    return __pthread_clock_gettime64 (clock_id, freq, tp);
 
   /* Get the current counter.  */
   HP_TIMING_NOW (tsc);
@@ -76,20 +76,20 @@ hp_timing_gettime (clockid_t clock_id, struct timespec *tp)
 
 
 static inline int
-realtime_gettime (struct timespec *tp)
+realtime_gettime (struct __timespec64 *tp)
 {
   struct timeval tv;
   int retval = __gettimeofday (&tv, NULL);
   if (retval == 0)
     /* Convert into `timespec'.  */
-    TIMEVAL_TO_TIMESPEC (&tv, tp);
+    valid_timeval_to_timespec64 (&tv, tp);
   return retval;
 }
 
 
 /* Get current value of CLOCK and store it in TP.  */
 int
-__clock_gettime (clockid_t clock_id, struct timespec *tp)
+__clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp)
 {
   int retval = -1;
 
@@ -103,9 +103,9 @@ __clock_gettime (clockid_t clock_id, struct timespec *tp)
     case CLOCK_REALTIME:
       {
        struct timeval tv;
-       retval = __gettimeofday (&tv, NULL);
+       retval = __gettimeofday (&tv32, NULL);
        if (retval == 0)
-         TIMEVAL_TO_TIMESPEC (&tv, tp);
+         valid_timeval_to_timespec64 (&tv32, tp);
       }
       break;
 #endif
@@ -132,5 +132,36 @@ __clock_gettime (clockid_t clock_id, struct timespec *tp)
 
   return retval;
 }
+
+int
+__clock_gettime (clockid_t clock_id, struct timespec *tp)
+{
+  struct __timespec64 ts64;
+  int res;
+
+  if (tp == NULL)
+    {
+      __set_errno(EINVAL);
+      res = -1;
+    }
+  else
+    {
+      res = __clock_gettime64 (clock_id, &ts64);
+      if (res == 0)
+       {
+         if (fits_in_time_t (ts64.tv_sec))
+           {
+             tp->tv_sec = ts64.tv_sec;
+             tp->tv_nsec = ts64.tv_nsec;
+           }
+         else
+           {
+             __set_errno(EOVERFLOW);
+             res = -1;
+           }
+       }
+    }
+  return res;
+}
 weak_alias (__clock_gettime, clock_gettime)
 libc_hidden_def (__clock_gettime)
index d837fa36b1b901e5d8fcf40aafa526cebefea708..9920ffa1ab1c42f1b299ca1f8c3007f37e608987 100644 (file)
 # define HAVE_VSYSCALL
 #endif
 #include <sysdep-vdso.h>
+#include <y2038-support.h>
+
+# define DO_CLOCK_GETTIME_32 \
+  retval = INLINE_VSYSCALL (clock_gettime, 2, clock_id, &ts32);                \
+  if (retval == 0)                                                     \
+    {                                                                  \
+      valid_timespec_to_timespec64 (&ts32, tp);                                \
+    }
+
+#ifdef __NR_clock_gettime64
+
+/* We are building with a 64-bit-time clock_gettime syscall */
+
+# define DO_CLOCK_GETTIME_64 \
+    if (__y2038_linux_support > 0)                                     \
+      {                                                                        \
+       retval = INLINE_SYSCALL (clock_gettime64, 2, clock_id, tp);     \
+       if (retval == -1 && errno == ENOSYS)                            \
+         {                                                             \
+           __y2038_linux_support = -1;                                 \
+           DO_CLOCK_GETTIME_32;                                        \
+         }                                                             \
+      }                                                                        \
+    else                                                               \
+      {                                                                        \
+        DO_CLOCK_GETTIME_32;                                           \
+      }
+
+#else
+
+/* We are building without a 64-bit-time clock_gettime syscall */
+
+# define DO_CLOCK_GETTIME_64 DO_CLOCK_GETTIME_32
+
+#endif
 
 /* The REALTIME and MONOTONIC clock are definitely supported in the
    kernel.  */
@@ -32,7 +67,7 @@
   SYSDEP_GETTIME_CPUTIME;                                                    \
   case CLOCK_REALTIME:                                                       \
   case CLOCK_MONOTONIC:                                                              \
-    retval = INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp);               \
+    DO_CLOCK_GETTIME_64;                                                     \
     break
 
 /* We handled the REALTIME clock here.  */
 #define HANDLED_CPUTIME        1
 
 #define SYSDEP_GETTIME_CPU(clock_id, tp) \
-  retval = INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp); \
+  DO_CLOCK_GETTIME_64; \
   break
-#define SYSDEP_GETTIME_CPUTIME /* Default catches them too.  */
+
+#define SYSDEP_GETTIME_CPUTIME \
+  struct timespec ts32
 
 #include <sysdeps/unix/clock_gettime.c>