bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] year2038: port to unusual time_t platforms


From: Paul Eggert
Subject: [PATCH] year2038: port to unusual time_t platforms
Date: Mon, 2 Aug 2021 09:35:21 -0700

* m4/year2038.m4 (gl_YEAR2038_TEST_INCLUDES): Check that time_t
can go to 2**32 - 1, not to 2**63 - 1, as the former is enough to
be year 2038 safe.  Unsigned 32-bit time_t (AmigaOS) and signed
40-bit time_t (Unisys ClearPath) have occurred in the wild, and
even if Gnulib code is rarely or never ported to them there’s no
need to exclude them merely because of year 2038 issues.
(gl_YEAR2038_BODY): Adjust messages to match.  Use 2**32 - 1,
not 2**32, as the test timestamp, to allow unsigned 32-bit time_t.
---
 ChangeLog      | 12 ++++++++++
 m4/year2038.m4 | 61 +++++++++++++++++++++++++++++---------------------
 2 files changed, 48 insertions(+), 25 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 98fef6c6c..3027aa45f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2021-08-02  Paul Eggert  <eggert@cs.ucla.edu>
+
+       year2038: port to unusual time_t platforms
+       * m4/year2038.m4 (gl_YEAR2038_TEST_INCLUDES): Check that time_t
+       can go to 2**32 - 1, not to 2**63 - 1, as the former is enough to
+       be year 2038 safe.  Unsigned 32-bit time_t (AmigaOS) and signed
+       40-bit time_t (Unisys ClearPath) have occurred in the wild, and
+       even if Gnulib code is rarely or never ported to them there’s no
+       need to exclude them merely because of year 2038 issues.
+       (gl_YEAR2038_BODY): Adjust messages to match.  Use 2**32 - 1,
+       not 2**32, as the test timestamp, to allow unsigned 32-bit time_t.
+
 2021-08-01  Paul Eggert  <eggert@cs.ucla.edu>
 
        xalloc: no attribute (malloc (free)) on inline
diff --git a/m4/year2038.m4 b/m4/year2038.m4
index ad7f30358..7ae004e81 100644
--- a/m4/year2038.m4
+++ b/m4/year2038.m4
@@ -1,11 +1,11 @@
-# year2038.m4 serial 5
+# year2038.m4 serial 6
 dnl Copyright (C) 2017-2021 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
 dnl with or without modifications, as long as this notice is preserved.
 
-dnl Attempt to ensure that 'time_t' is a 64-bit type
-dnl and that the functions time(), stat(), etc. return 64-bit times.
+dnl Attempt to ensure that 'time_t' can go past the year 2038 and that
+dnl the functions 'time', 'stat', etc. work with post-2038 timestamps.
 
 AC_DEFUN([gl_YEAR2038_EARLY],
 [
@@ -23,18 +23,15 @@ AC_DEFUN([gl_YEAR2038_EARLY],
 AC_DEFUN([gl_YEAR2038_TEST_INCLUDES],
 [[
   #include <time.h>
-  /* Check that time_t can represent 2**63 - 1 correctly.
-     We can't simply define LARGE_TIME_T to be 9223372036854775807,
-     since some C++ compilers masquerading as C compilers
-     incorrectly reject 9223372036854775807.  */
-  #define LARGE_TIME_T (((time_t) 1 << 31 << 31) - 1 + ((time_t) 1 << 31 << 
31))
-  int verify_time_t_range[(LARGE_TIME_T % 2147483629 == 721
-                           && LARGE_TIME_T % 2147483647 == 1)
+  /* Check that time_t can represent 2**32 - 1 correctly.  */
+  #define LARGE_TIME_T (((time_t) 1 << 30) - 1 + 3 * ((time_t) 1 << 30))
+  int verify_time_t_range[(LARGE_TIME_T / 65537 == 65535
+                           && LARGE_TIME_T % 65537 == 0)
                           ? 1 : -1];
 ]])
 
-# gl_YEAR2038_BODY(REQUIRE-64-BIT)
-----------------------------------
+# gl_YEAR2038_BODY(REQUIRE-YEAR2038-SAFE)
+-----------------------------------------
 AC_DEFUN([gl_YEAR2038_BODY],
 [
  AC_ARG_ENABLE([year2038],
@@ -54,12 +51,12 @@ AC_DEFUN([gl_YEAR2038_BODY],
   dnl alias of __time64_t.
   dnl And when compiling with -D_USE_32BIT_TIME_T, time_t is an alias of
   dnl __time32_t.
-  AC_CACHE_CHECK([for 64-bit time_t], [gl_cv_type_time_t_64],
+  AC_CACHE_CHECK([for time_t past the year 2038], [gl_cv_type_time_t_y2038],
     [AC_COMPILE_IFELSE(
        [AC_LANG_SOURCE([gl_YEAR2038_TEST_INCLUDES])],
-       [gl_cv_type_time_t_64=yes], [gl_cv_type_time_t_64=no])
+       [gl_cv_type_time_t_y2038=yes], [gl_cv_type_time_t_y2038=no])
     ])
-  if test "$gl_cv_type_time_t_64" = no; then
+  if test "$gl_cv_type_time_t_y2038" = no; then
     AC_CACHE_CHECK([for 64-bit time_t with _TIME_BITS=64],
       [gl_cv_type_time_t_bits_macro],
       [AC_COMPILE_IFELSE(
@@ -75,10 +72,10 @@ AC_DEFUN([gl_YEAR2038_BODY],
       dnl AC_SYS_LARGFILE also defines this; it's OK if we do too.
       AC_DEFINE([_FILE_OFFSET_BITS], [64],
         [Number of bits in a file offset, on hosts where this is settable.])
-      gl_cv_type_time_t_64=yes
+      gl_cv_type_time_t_y2038=yes
     fi
   fi
-  if test $gl_cv_type_time_t_64 = no; then
+  if test $gl_cv_type_time_t_y2038 = no; then
     AC_COMPILE_IFELSE(
       [AC_LANG_SOURCE(
          [[#ifdef _USE_32BIT_TIME_T
@@ -87,20 +84,34 @@ AC_DEFUN([gl_YEAR2038_BODY],
              error fail
            #endif
          ]])],
-      [AC_MSG_FAILURE([This package requires a 64-bit 'time_t' type. Remove 
_USE_32BIT_TIME_T from the compiler flags.])],
+      [AC_MSG_FAILURE(
+         [The 'time_t' type stops working after January 2038.
+          Remove _USE_32BIT_TIME_T from the compiler flags.])],
       [# If not cross-compiling and $1 says we should check,
-       # and 'touch' works with a large timestamp, then evidently 64-bit time_t
+       # and 'touch' works with a large timestamp, then evidently wider time_t
        # is desired and supported, so fail and ask the builder to fix the
        # problem.  Otherwise, just warn the builder.
        m4_ifval([$1],
          [if test $cross_compiling = no \
-             && TZ=UTC0 touch -t 210602070628.16 conftest.time 2>/dev/null; 
then
+             && TZ=UTC0 touch -t 210602070628.15 conftest.time 2>/dev/null; 
then
+            case `TZ=UTC0 LC_ALL=C ls -l conftest.time 2>/dev/null` in
+              *'Feb  7  2106'* | *'Feb  7 17:10'*)
+                AC_MSG_FAILURE(
+                  [The 'time_t' type stops working after January 2038,
+                   and your system appears to support a wider 'time_t'.
+                   Try configuring with 'CPPFLAGS="-m64" LDFLAGS="-m64"'.
+                   To build with a 32-bit time_t anyway (not recommended),
+                   configure with '--disable-year2038'.]);;
+            esac
             rm -f conftest.time
-            AC_MSG_FAILURE([This package requires a 64-bit 'time_t' type, 
which your system appears to support. You might try configuring with 
'CPPFLAGS="-m64" LDFLAGS="-m64"'. To build with a 32-bit time_t anyway (not 
recommended), configure with '--disable-year2038'.])
           fi])
-       if test "$gl_warned_about_64_bit_time_t" != yes; then
-         AC_MSG_WARN([This package requires a 64-bit 'time_t' type if there is 
any way to access timestamps outside the year range 1901-2038 on your platform. 
Perhaps you should configure with 'CPPFLAGS="-m64" LDFLAGS="-m64"'?])
-         gl_warned_about_64_bit_time_t=yes
+       if test "$gl_warned_about_y2038" != yes; then
+         AC_MSG_WARN(
+           [The 'time_t' type stops working after January 2038,
+            and this package needs a wider 'time_t' type
+            if there is any way to access timestamps after that.
+            Configure with 'CPPFLAGS="-m64" LDFLAGS="-m64"' perhaps?])
+         gl_warned_about_y2038=yes
        fi
       ])
   fi])
@@ -108,5 +119,5 @@ AC_DEFUN([gl_YEAR2038_BODY],
 
 AC_DEFUN([gl_YEAR2038],
 [
-  gl_YEAR2038_BODY([require-64-bit])
+  gl_YEAR2038_BODY([require-year2038-safe])
 ])
-- 
2.30.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]