This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[RFC 1/7] y2038: Introduce struct __timespec64
- From: Lukasz Majewski <lukma at denx dot de>
- To: libc-alpha at sourceware dot org, Joseph Myers <joseph at codesourcery dot com>
- Cc: Paul Eggert <eggert at cs dot ucla dot edu>, Zack Weinberg <zackw at panix dot com>, Lukasz Majewski <lukma at denx dot de>
- Date: Wed, 27 Mar 2019 09:52:04 +0100
- Subject: [RFC 1/7] y2038: Introduce struct __timespec64
- References: <20190327085210.22019-1-lukma@denx.de>
This type is a glibc's type similar to struct timespec
but whose tv_sec field is a __time64_t rather than a time_t,
which makes it Y2038-proof and usable to pass between user
code and Y2038-proof kernel syscalls (e.g. clock_gettime()).
On 64-bit architectures, and on X32, struct __timespec64 is
just an alias of struct timespec, which is already 64-bit.
On other architectures, it must be explicitly defined.
When passing this structure to the kernel - it ensures that the
higher half of tv_nsec is always 0, which means that glibc
can reuse the public type (as tv_pad is zeroed anyway).
Moreover, the tv_nsec has an anonymous 32 bit padding (ordered
according to the endianness of the architecture) to prevent user space
programs, depending on long, 32 bit, tv_nsec from breaking.
Tested on x86_64 and ARM.
* time/bits/types/struct___timespec64.h:
Create new file time/bits/types/struct___timespec64.h
* include/time.h: Add # include <time/bits/types/struct___timespec64.h>
* time/Makefile:
Add bits/types/struct___timespec64.h to Makefile's headers
---
include/time.h | 1 +
time/Makefile | 2 +-
time/bits/types/struct___timespec64.h | 39 +++++++++++++++++++++++++++++++++++
3 files changed, 41 insertions(+), 1 deletion(-)
create mode 100644 time/bits/types/struct___timespec64.h
diff --git a/include/time.h b/include/time.h
index ac3163c2a5..d8a3ef35e2 100644
--- a/include/time.h
+++ b/include/time.h
@@ -5,6 +5,7 @@
# include <bits/types/locale_t.h>
# include <stdbool.h>
# include <time/mktime-internal.h>
+# include <time/bits/types/struct___timespec64.h>
extern __typeof (strftime_l) __strftime_l;
libc_hidden_proto (__strftime_l)
diff --git a/time/Makefile b/time/Makefile
index 5c6304ece1..dc9ad55678 100644
--- a/time/Makefile
+++ b/time/Makefile
@@ -27,7 +27,7 @@ headers := time.h sys/time.h sys/timeb.h bits/time.h \
bits/types/struct_itimerspec.h \
bits/types/struct_timespec.h bits/types/struct_timeval.h \
bits/types/struct_tm.h bits/types/timer_t.h \
- bits/types/time_t.h
+ bits/types/time_t.h bits/types/struct___timespec64.h
routines := offtime asctime clock ctime ctime_r difftime \
gmtime localtime mktime time \
diff --git a/time/bits/types/struct___timespec64.h b/time/bits/types/struct___timespec64.h
new file mode 100644
index 0000000000..9946717af6
--- /dev/null
+++ b/time/bits/types/struct___timespec64.h
@@ -0,0 +1,39 @@
+/* NB: Include guard matches what <linux/time.h> uses. */
+/* #ifndef _STRUCT_TIMESPEC
+# error "Never include <bits/types/struct___timespec64.h> directly !"
+#endif */
+
+#ifndef _STRUCT___TIMESPEC64
+#define _STRUCT___TIMESPEC64 1
+
+#include <bits/types.h>
+#include <bits/timesize.h>
+#include <endian.h>
+
+/* The glibc Y2038-proof structure for a time value.
+ To keep things Posix-ish, we keep the nanoseconds field a 32-bit
+ signed long, but since the Linux field is a 64-bit signed int, we
+ pad our tv_nsec with a 32-bit bitfield, which should always be 0.
+ */
+#if __TIMESIZE==64
+# define __timespec64 timespec
+#else
+#define TIMSPEC64_TV_PAD_DEFINED
+# if BYTE_ORDER == BIG_ENDIAN
+struct __timespec64
+{
+ __time64_t tv_sec; /* Seconds */
+ int tv_pad: 32; /* Padding named for checking/setting */
+ __syscall_slong_t tv_nsec; /* Nanoseconds */
+};
+# else
+struct __timespec64
+{
+ __time64_t tv_sec; /* Seconds */
+ __syscall_slong_t tv_nsec; /* Nanoseconds */
+ int tv_pad: 32; /* Padding named for checking/setting */
+};
+# endif
+#endif
+
+#endif
--
2.11.0