This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[RFC v2 02/20] y2038: Provide conversion helpers for struct __timespec64
- From: Alistair Francis <alistair dot francis at wdc dot com>
- To: libc-alpha at sourceware dot org
- Cc: arnd at arndb dot de, adhemerval dot zanella at linaro dot org, fweimer at redhat dot com, palmer at sifive dot com, macro at wdc dot com, zongbox at gmail dot com, zong at andestech dot com, alistair dot francis at wdc dot com, alistair23 at gmail dot com
- Date: Mon, 24 Jun 2019 17:08:49 -0700
- Subject: [RFC v2 02/20] y2038: Provide conversion helpers for struct __timespec64
- Ironport-sdr: whGIo/T7Qtk9wn0OEAGlOXiuSrdYv1yyPTjammQ+SUDVQx3tm/TeyFxsd3GZzM4qf40RHQ9cp2 9EuLaTKbMArUwz7iEGUwAkyUsddje90jL5zZkdFvWUjsTQ5eTqrw5m4k4vnP4BG2eMCcKxovGk 4SYHahuVvLE3G3G14rY+3lr8wTN+DmJkzuVGnOG6ynTv/zqd8UFzoj2UB4HwR6xnmi+wkjRIlq qk0TKdzBmy2JWaTj681fZQvtpA/ysRLnFDlop8RW60pbzJYx7ejyXtpyXdNQQIlvhkOHx7S9hM iyunpk3VO3JxLF2tDeR7oZC8
- Ironport-sdr: CkeKgly+DWckstWaPdB1o4HnKoiN+X09aHiY/ZQhPqnDPX8CEFJKkHc/CGwMEF4QxSAFTvD/TS JZNhuvOvWXrTdrCd+nl0TX1RrlJLRRzg5esHMF06QDZFnzvLCHMWOuCEEIZTQlqJpki/5COFqR xJO5OKuuF+tdSqE1Dpav/vrqAOST2ax7fFd2IvuL/Yyv76GvCJdBkvoEAetPtevo5Jmaq7fxo2 P7HgXHkLSQgMrFo8x+yJykZSA/zVWuqnaPCd5AKr7WR25onMLeDkgZ6WzRNU9U/xyNmEFcNtfo rVM=
- References: <cover.1561421042.git.alistair.francis@wdc.com>
From: Lukasz Majewski <lukma@denx.de>
Those functions allow easy conversion between Y2038 safe struct
__timespec64 and other time related data structures (like struct timeval).
Moreover, those functions are NOT compiled when 64 bit time support is
enabled (i.e. the __ASSUME_TIME64_SYSCALLS is defined) and are used only
in 32 bit wrappers (like e.g. __clock_settime()).
* include/time.h (valid_timeval_to_timespec64): Add.
* include/time.h (valid_timespec_to_timespec64): Likewise.
* include/time.h (valid_timespec64_to_timespec): Likewise.
* include/time.h (valid_timespec64_to_timeval): Likewise.
* include/time.h (IS_VALID_NANOSECONDS): Likewise.
* include/time.h (timespec_to_timespec64): Likewise.
* include/time.h (timespec64_to_timespec): Likewise.
* include/time.h (timespec64_to_timeval): Likewise.
---
include/time.h | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 85 insertions(+)
diff --git a/include/time.h b/include/time.h
index 33d0fcb0fe..1b38d019c8 100644
--- a/include/time.h
+++ b/include/time.h
@@ -181,5 +181,90 @@ in_time_t_range (__time64_t t)
return s == t;
}
+# ifndef __ASSUME_TIME64_SYSCALLS
+/* Convert a known valid struct timeval into a struct __timespec64. */
+static inline void
+valid_timeval_to_timespec64 (const struct timeval *tv32,
+ struct __timespec64 *ts64)
+{
+ ts64->tv_sec = tv32->tv_sec;
+ ts64->tv_nsec = tv32->tv_usec * 1000;
+}
+
+/* Convert a known valid struct timespec into a struct __timespec64. */
+static inline void
+valid_timespec_to_timespec64 (const struct timespec *ts32,
+ struct __timespec64 *ts64)
+{
+ ts64->tv_sec = ts32->tv_sec;
+ ts64->tv_nsec = ts32->tv_nsec;
+}
+
+/* Convert a known valid struct __timespec64 into a struct timespec. */
+static inline void
+valid_timespec64_to_timespec (const struct __timespec64 *ts64,
+ struct timespec *ts32)
+{
+ ts32->tv_sec = (time_t) ts64->tv_sec;
+ ts32->tv_nsec = ts64->tv_nsec;
+}
+
+/* Convert a known valid struct __timespec64 into a struct timeval. */
+static inline void
+valid_timespec64_to_timeval (const struct __timespec64 *ts64,
+ struct timeval *tv32)
+{
+ tv32->tv_sec = (time_t) ts64->tv_sec;
+ tv32->tv_usec = ts64->tv_nsec / 1000;
+}
+
+/* Check if a value lies with the valid nanoseconds range. */
+#define IS_VALID_NANOSECONDS(ns) ((ns) >= 0 && (ns) <= 999999999)
+
+/* Check and convert a struct timespec into a struct __timespec64. */
+static inline bool
+timespec_to_timespec64 (const struct timespec *ts32,
+ struct __timespec64 *ts64)
+{
+ /* Check that ts32 holds a valid count of nanoseconds. */
+ if (! IS_VALID_NANOSECONDS (ts32->tv_nsec))
+ return false;
+ /* All ts32 fields can fit in ts64, so copy them. */
+ valid_timespec_to_timespec64 (ts32, ts64);
+ return true;
+}
+
+/* Check and convert a struct __timespec64 into a struct timespec. */
+static inline bool
+timespec64_to_timespec (const struct __timespec64 *ts64,
+ struct timespec *ts32)
+{
+ /* Check that tv_nsec holds a valid count of nanoseconds. */
+ if (! IS_VALID_NANOSECONDS (ts64->tv_nsec))
+ return false;
+ /* Check that tv_sec can fit in a __time_t. */
+ if (! in_time_t_range (ts64->tv_sec))
+ return false;
+ /* All ts64 fields can fit in ts32, so copy them. */
+ valid_timespec64_to_timespec (ts64, ts32);
+ return true;
+}
+
+/* Check and convert a struct __timespec64 into a struct timeval. */
+static inline bool
+timespec64_to_timeval (const struct __timespec64 *ts64,
+ struct timeval *tv32)
+{
+ /* Check that tv_nsec holds a valid count of nanoseconds. */
+ if (! IS_VALID_NANOSECONDS (ts64->tv_nsec))
+ return false;
+ /* Check that tv_sec can fit in a __time_t. */
+ if (! in_time_t_range (ts64->tv_sec))
+ return false;
+ /* All ts64 fields can fit in tv32, so copy them. */
+ valid_timespec64_to_timeval (ts64, tv32);
+ return true;
+}
+# endif
#endif
#endif
--
2.22.0