[RFC,6/7] y2038: Support for Y2038 safe time on 32 bit systems (generic code)

Message ID 20190327085210.22019-7-lukma@denx.de
State Superseded
Headers

Commit Message

Lukasz Majewski March 27, 2019, 8:52 a.m. UTC
  * include/features.h:
  Add logic to set __USE_TIME_BITS64 according to passed (when building
  userspace Y2038 safe program on 32 bit system) _TIME_BITS and
  _FILE_OFFSET_BITS
* manual/creature.texi: Add description of _TIME_BITS
* time/bits/types/struct_timespec.h:
  Add "aliasing" (in preprocessor level) for struct timespec to struct
  __timespec64 (in userspace) when running on 32 bit system with Y2038
  support
* time/bits/types/time_t.h:
  Use __time64_t as time_t when __USE_TIME_BITS64 is defined
---
 include/features.h                | 19 +++++++++++++++++++
 manual/creature.texi              | 28 ++++++++++++++++++++++++++++
 time/bits/types/struct_timespec.h |  8 ++++++++
 time/bits/types/time_t.h          |  4 ++++
 4 files changed, 59 insertions(+)
  

Comments

Joseph Myers March 27, 2019, 1:47 p.m. UTC | #1
On Wed, 27 Mar 2019, Lukasz Majewski wrote:

> * include/features.h:
>   Add logic to set __USE_TIME_BITS64 according to passed (when building
>   userspace Y2038 safe program on 32 bit system) _TIME_BITS and
>   _FILE_OFFSET_BITS

Nothing like this should be added until *every* public API has support for 
_TIME_BITS=64 (then the support for it should be added for all APIs at 
once - all the header changes and all the new symbol versions).

> +/* we need to know the word size in order to check the time size */

Comment style.

> +#if defined _TIME_BITS
> +# if _TIME_BITS == 64
> +#  if ! defined(_FILE_OFFSET_BITS) || _FILE_OFFSET_BITS != 64

Space before '('

> +#   error _TIME_BIT==64 is allowed only when _FILE_OFFSET_BITS==64

> +#   error __TIME_BITS=32 is not compatible with __WORDSIZE > 32

It should be _TIME_BITS.  Not _TIME_BIT, not __TIME_BITS.  Please spell 
the name consistently throughout.
  

Patch

diff --git a/include/features.h b/include/features.h
index e016b3e5c7..bf1d3ccb4f 100644
--- a/include/features.h
+++ b/include/features.h
@@ -365,6 +365,25 @@ 
 # define __USE_FILE_OFFSET64	1
 #endif
 
+/* we need to know the word size in order to check the time size */
+#include <bits/wordsize.h>
+
+#if defined _TIME_BITS
+# if _TIME_BITS == 64
+#  if ! defined(_FILE_OFFSET_BITS) || _FILE_OFFSET_BITS != 64
+#   error _TIME_BIT==64 is allowed only when _FILE_OFFSET_BITS==64
+#  elif __WORDSIZE == 32
+#   define __USE_TIME_BITS64	1
+#  endif
+# elif __TIME_BITS == 32
+#  if __WORDSIZE > 32
+#   error __TIME_BITS=32 is not compatible with __WORDSIZE > 32
+#  endif
+# else
+#  error Invalid _TIME_BITS value (can only be 32 or 64)
+# endif
+#endif
+
 #if defined _DEFAULT_SOURCE
 # define __USE_MISC	1
 #endif
diff --git a/manual/creature.texi b/manual/creature.texi
index 8876b2ab77..10b7111043 100644
--- a/manual/creature.texi
+++ b/manual/creature.texi
@@ -165,6 +165,34 @@  This macro was introduced as part of the Large File Support extension
 (LFS).
 @end defvr
 
+@defvr Macro _TIME_BITS
+This macro determines the bit size of @code{time_t} (and therefore the
+bit size of all @code{time_t} derived types and the prototypes of all
+related functions). If @code{_TIME_BITS} is undefined, the bit size of
+time_t equals the bit size of the architecture.
+
+If @code{_TIME_BITS} is undefined, or if @code{_TIME_BITS} is defined
+to the value @code{32} and @code{__WORDSIZE} is defined to the value
+@code{32}, or or if @code{_TIME_BITS} is defined to the value @code{64}
+and @code{__WORDSIZE} is defined to the value @code{64}, nothing changes.
+
+If @code{_TIME_BITS} is defined to the value @code{64} and if
+@code{__WORDSIZE} is defined to the value @code{32}, then the @w{64 bit}
+time API and implementation are used even though the architecture word
+size is @code{32}. Also, if the kernel provides @w{64 bit} time support,
+it is used; otherwise, the @w{32 bit} kernel time support is used (with
+no provision to address kernel Y2038 shortcomings).
+
+If @code{_TIME_BITS} is defined to the value @code{32} and if
+@code{__WORDSIZE} is defined to the value @code{64}, then a compile-time
+error is emitted.
+
+If @code{_TIME_BITS} is defined to a value different from both @code{32}
+and @code{64}, then a compile-time error is emitted.
+
+This macro was introduced as part of the Y2038 support.
+@end defvr
+
 @defvr Macro _ISOC99_SOURCE
 @standards{GNU, (none)}
 If this macro is defined, features from ISO C99 are included.  Since
diff --git a/time/bits/types/struct_timespec.h b/time/bits/types/struct_timespec.h
index 5b77c52b4f..fc5a7ec25b 100644
--- a/time/bits/types/struct_timespec.h
+++ b/time/bits/types/struct_timespec.h
@@ -4,6 +4,9 @@ 
 
 #include <bits/types.h>
 
+/* Use the original definition for 64-bit arches
+   or when 64-bit-time by default has *not* been requested */
+#if __WORDSIZE > 32 || ! defined(__USE_TIME_BITS64)
 /* POSIX.1b structure for a time value.  This is like a `struct timeval' but
    has nanoseconds instead of microseconds.  */
 struct timespec
@@ -11,5 +14,10 @@  struct timespec
   __time_t tv_sec;		/* Seconds.  */
   __syscall_slong_t tv_nsec;	/* Nanoseconds.  */
 };
+#else
+# include <bits/types/struct___timespec64.h>
+/* Use the 64-bit-time timespec by default */
+#define timespec __timespec64
+# endif
 
 #endif
diff --git a/time/bits/types/time_t.h b/time/bits/types/time_t.h
index ab8287c6fe..84d67f6ac3 100644
--- a/time/bits/types/time_t.h
+++ b/time/bits/types/time_t.h
@@ -4,6 +4,10 @@ 
 #include <bits/types.h>
 
 /* Returned by `time'.  */
+#ifdef __USE_TIME_BITS64
+typedef __time64_t time_t;
+#else
 typedef __time_t time_t;
+#endif
 
 #endif