[1/2] Y2038: add type __time64_t
Commit Message
This type is public, so that time_t can be a typedef of it
when we switch the public API to 64-bit time.
Also, provide a function to check if a __time64_t value
fits in a (32-bit) __time_t.
---
bits/typesizes.h | 1 +
include/time.h | 9 ++++++++-
posix/bits/types.h | 3 ++-
sysdeps/mach/hurd/bits/typesizes.h | 1 +
sysdeps/unix/sysv/linux/alpha/bits/typesizes.h | 1 +
sysdeps/unix/sysv/linux/generic/bits/typesizes.h | 1 +
sysdeps/unix/sysv/linux/s390/bits/typesizes.h | 1 +
sysdeps/unix/sysv/linux/sparc/bits/typesizes.h | 1 +
sysdeps/unix/sysv/linux/x86/bits/typesizes.h | 1 +
9 files changed, 17 insertions(+), 2 deletions(-)
Comments
Albert ARIBAUD (3ADEV) wrote:
> -__STD_TYPE __TIME_T_TYPE __time_t; /* Seconds since the Epoch. */
> +__STD_TYPE __TIME_T_TYPE __time_t; /* Seconds since the Epoch, Y2038-unsafe. */
This change to commentary is confusing, as __time_t is Y2038-safe on 64-bit
hosts. I suggest omitting the change, and changing the comment on the next line
to "Seconds since the Epoch (TIME_BITS==64)" (or whatever the name of that macro
is).
Hi Paul,
On Wed, 13 Jun 2018 01:38:09 -0700, Paul Eggert <eggert@cs.ucla.edu>
wrote :
> Albert ARIBAUD (3ADEV) wrote:
> > -__STD_TYPE __TIME_T_TYPE __time_t; /* Seconds since the Epoch. */
> > +__STD_TYPE __TIME_T_TYPE __time_t; /* Seconds since the Epoch, Y2038-unsafe. */
>
> This change to commentary is confusing, as __time_t is Y2038-safe on 64-bit
> hosts. I suggest omitting the change, and changing the comment on the next line
> to "Seconds since the Epoch (TIME_BITS==64)" (or whatever the name of that macro
> is).
Fixed locally as suggested, will repost once 2/2 discussion is complete.
Cordialement,
Albert ARIBAUD
3ADEV
There is a key definition you are missing in this patch: one that says
whether the particular glibc configuration supports 32-bit time_t at all.
This new macro could go in bits/wordsize.h, or in its own installed
header. The value is normally the same as (__WORDSIZE == 32), *except* on
x32, which already has 64-bit time_t despite 32-bit wordsize.
The new macro would be used, in the installed headers, to control whether
an explicit _TIME_BITS=32 is valid or not. It would also be used, in
glibc internals, to control whether there are separate 32-bit interfaces
that wrap 64-bit ones, or whether the 64-bit names are just #defined to
the generic ones (#define __clock_gettime64 __clock_gettime, in some
internal header, for example) to avoid creating any new interfaces in the
case where time_t is already 64-bit, while avoiding the need for lots of
conditionals where glibc-internal code written for 64-bit time_t wishes to
call such interfaces.
Hi Joseph,
On Wed, 13 Jun 2018 14:13:00 +0000, Joseph Myers
<joseph@codesourcery.com> wrote :
> There is a key definition you are missing in this patch: one that says
> whether the particular glibc configuration supports 32-bit time_t at all.
>
> This new macro could go in bits/wordsize.h, or in its own installed
> header. The value is normally the same as (__WORDSIZE == 32), *except* on
> x32, which already has 64-bit time_t despite 32-bit wordsize.
>
> The new macro would be used, in the installed headers, to control whether
> an explicit _TIME_BITS=32 is valid or not. It would also be used, in
> glibc internals, to control whether there are separate 32-bit interfaces
> that wrap 64-bit ones, or whether the 64-bit names are just #defined to
> the generic ones (#define __clock_gettime64 __clock_gettime, in some
> internal header, for example) to avoid creating any new interfaces in the
> case where time_t is already 64-bit, while avoiding the need for lots of
> conditionals where glibc-internal code written for 64-bit time_t wishes to
> call such interfaces.
Which would be best:
- a "boolean" macro (e.g. __TIMESIZE32) defined as (__WORDSIZE == 32)
except for x32 where it would be defined as 1, or
- a "size" macro (e.g. __TIMESIZE) defined equal to __WORDSIZE except
for x32 where it would be defined as 64?
I have a slight preference for the "size" form.
Cordialement,
Albert ARIBAUD
3ADEV
Albert ARIBAUD wrote:
> - a "size" macro (e.g. __TIMESIZE) defined equal to __WORDSIZE except
> for x32 where it would be defined as 64?
>
> I have a slight preference for the "size" form.
Works for me. Though C11 uses _WIDTH for names that count bit widths of
integers, so I'd mildly prefer __TIME_WIDTH as it is a new name.
On Wed, 13 Jun 2018, Paul Eggert wrote:
> Albert ARIBAUD wrote:
> > - a "size" macro (e.g. __TIMESIZE) defined equal to __WORDSIZE except
> > for x32 where it would be defined as 64?
> >
> > I have a slight preference for the "size" form.
>
> Works for me. Though C11 uses _WIDTH for names that count bit widths of
> integers, so I'd mildly prefer __TIME_WIDTH as it is a new name.
Whatever the name, it needs to be clear that this macro relates to the
time_t used by default (unsuffixed) functions in this glibc - *not*
necessarily the time_t for the current compilation. (Rather, _TIME_BITS
== 64 && (new macro) == 32 would be the condition for the installed
headers to need to redirect calls to time-related functions.)
The width macros are from TS 18661-1, not C11 (hopefully they'll end up as
an unconditional feature of C2x without requiring
__STDC_WANT_IEC_60559_BFP_EXT__, since there is demand for them outside
the floating-point context of passing them to the fromfp functions). If
there were a TIME_WIDTH addition to that set of macros, I'd expect it to
relate to the current compilation.
On 06/13/2018 09:39 AM, Joseph Myers wrote:
> Whatever the name, it needs to be clear that this macro relates to the
> time_t used by default (unsuffixed) functions in this glibc -*not*
> necessarily the time_t for the current compilation.
OK, in that case perhaps it's better to stick to __TIMESIZE, as the
_WIDTH names are intended to apply to the current compilation. (Sorry
about confusing C11 with TS 18661-1.)
@@ -48,6 +48,7 @@
#define __ID_T_TYPE __U32_TYPE
#define __CLOCK_T_TYPE __SLONGWORD_TYPE
#define __TIME_T_TYPE __SLONGWORD_TYPE
+#define __TIME64_T_TYPE __SQUAD_TYPE
#define __USECONDS_T_TYPE __U32_TYPE
#define __SUSECONDS_T_TYPE __SLONGWORD_TYPE
#define __DADDR_T_TYPE __S32_TYPE
@@ -3,6 +3,7 @@
#ifndef _ISOMAC
# include <bits/types/locale_t.h>
+# include <stdbool.h>
extern __typeof (strftime_l) __strftime_l;
libc_hidden_proto (__strftime_l)
@@ -101,10 +102,16 @@ extern char * __strptime_internal (const char *rp, const char *fmt,
extern double __difftime (time_t time1, time_t time0);
-
/* Use in the clock_* functions. Size of the field representing the
actual clock ID. */
#define CLOCK_IDFIELD_SIZE 3
+/* check whether a time64_t value fits in a time_t */
+static inline bool
+fits_in_time_t (__time64_t t)
+{
+ return t == (time_t) t;
+}
+
#endif
#endif
@@ -155,7 +155,8 @@ __STD_TYPE __CLOCK_T_TYPE __clock_t; /* Type of CPU usage counts. */
__STD_TYPE __RLIM_T_TYPE __rlim_t; /* Type for resource measurement. */
__STD_TYPE __RLIM64_T_TYPE __rlim64_t; /* Type for resource measurement (LFS). */
__STD_TYPE __ID_T_TYPE __id_t; /* General type for IDs. */
-__STD_TYPE __TIME_T_TYPE __time_t; /* Seconds since the Epoch. */
+__STD_TYPE __TIME_T_TYPE __time_t; /* Seconds since the Epoch, Y2038-unsafe. */
+__STD_TYPE __TIME64_T_TYPE __time64_t; /* Seconds since the Epoch, Y2038-safe. */
__STD_TYPE __USECONDS_T_TYPE __useconds_t; /* Count of microseconds. */
__STD_TYPE __SUSECONDS_T_TYPE __suseconds_t; /* Signed count of microseconds. */
@@ -48,6 +48,7 @@
#define __ID_T_TYPE __U32_TYPE
#define __CLOCK_T_TYPE __SLONGWORD_TYPE
#define __TIME_T_TYPE __SLONGWORD_TYPE
+#define __TIME64_T_TYPE __SQUAD_TYPE
#define __USECONDS_T_TYPE __U32_TYPE
#define __SUSECONDS_T_TYPE __SLONGWORD_TYPE
#define __DADDR_T_TYPE __S32_TYPE
@@ -47,6 +47,7 @@
#define __ID_T_TYPE __U32_TYPE
#define __CLOCK_T_TYPE __SLONGWORD_TYPE
#define __TIME_T_TYPE __SLONGWORD_TYPE
+#define __TIME64_T_TYPE __SQUAD_TYPE
#define __USECONDS_T_TYPE __U32_TYPE
#define __SUSECONDS_T_TYPE __S64_TYPE
#define __DADDR_T_TYPE __S32_TYPE
@@ -49,6 +49,7 @@
#define __ID_T_TYPE __U32_TYPE
#define __CLOCK_T_TYPE __SLONGWORD_TYPE
#define __TIME_T_TYPE __SLONGWORD_TYPE
+#define __TIME64_T_TYPE __SQUAD_TYPE
#define __USECONDS_T_TYPE __U32_TYPE
#define __SUSECONDS_T_TYPE __SLONGWORD_TYPE
#define __DADDR_T_TYPE __S32_TYPE
@@ -48,6 +48,7 @@
#define __ID_T_TYPE __U32_TYPE
#define __CLOCK_T_TYPE __SLONGWORD_TYPE
#define __TIME_T_TYPE __SLONGWORD_TYPE
+#define __TIME64_T_TYPE __SQUAD_TYPE
#define __USECONDS_T_TYPE __U32_TYPE
#define __SUSECONDS_T_TYPE __SLONGWORD_TYPE
#define __DADDR_T_TYPE __S32_TYPE
@@ -48,6 +48,7 @@
#define __ID_T_TYPE __U32_TYPE
#define __CLOCK_T_TYPE __SLONGWORD_TYPE
#define __TIME_T_TYPE __SLONGWORD_TYPE
+#define __TIME64_T_TYPE __SQUAD_TYPE
#define __USECONDS_T_TYPE __U32_TYPE
#define __SUSECONDS_T_TYPE __S32_TYPE
#define __DADDR_T_TYPE __S32_TYPE
@@ -62,6 +62,7 @@
#define __ID_T_TYPE __U32_TYPE
#define __CLOCK_T_TYPE __SYSCALL_SLONG_TYPE
#define __TIME_T_TYPE __SYSCALL_SLONG_TYPE
+#define __TIME64_T_TYPE __SQUAD_TYPE
#define __USECONDS_T_TYPE __U32_TYPE
#define __SUSECONDS_T_TYPE __SYSCALL_SLONG_TYPE
#define __DADDR_T_TYPE __S32_TYPE