bug-gnulib
[Top][All Lists]
Advanced

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

[PATCH] time_rz: work around Mac OS X 10.6 infloop


From: Paul Eggert
Subject: [PATCH] time_rz: work around Mac OS X 10.6 infloop
Date: Tue, 27 Mar 2018 13:23:36 -0700

* doc/posix-functions/localtime.texi:
* doc/posix-functions/localtime_r.texi: Mention the bug.
* lib/time_rz.c (localtime_rz): Work around the bug.  It’d be
better to fix localtime and localtime_r instead, but that would be
more work and is not needed to fix the Emacs problem.
* m4/time_rz.m4 (gl_TIME_RZ): Detect the bug.
---
 ChangeLog                            | 10 ++++++++++
 doc/posix-functions/localtime.texi   |  5 +++++
 doc/posix-functions/localtime_r.texi |  8 +++++++-
 lib/time_rz.c                        | 15 +++++++++++++++
 m4/time_rz.m4                        | 32 ++++++++++++++++++++++++++++++++
 5 files changed, 69 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 4b0890876..99f219c26 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2018-03-26  Paul Eggert  <address@hidden>
+
+       time_rz: work around Mac OS X 10.6 infloop
+       * doc/posix-functions/localtime.texi:
+       * doc/posix-functions/localtime_r.texi: Mention the bug.
+       * lib/time_rz.c (localtime_rz): Work around the bug.  It’d be
+       better to fix localtime and localtime_r instead, but that would be
+       more work and is not needed to fix the Emacs problem.
+       * m4/time_rz.m4 (gl_TIME_RZ): Detect the bug.
+
 2018-03-24  Jim Meyering  <address@hidden>
 
        test-version-etc.sh: don't use diff directly: use init.sh's compare
diff --git a/doc/posix-functions/localtime.texi 
b/doc/posix-functions/localtime.texi
index 02d069cc1..c8a2b83b0 100644
--- a/doc/posix-functions/localtime.texi
+++ b/doc/posix-functions/localtime.texi
@@ -16,6 +16,11 @@ when the environment variable @code{TZ} has been set by 
Cygwin.
 Portability problems not fixed by Gnulib:
 @itemize
 @item
+On some platforms, this function loops forever for values
+near extrema (such as the year @math{-2**31}):
+Mac OS X 10.6.
+You can use the @code{time_rz} module to work around the problem.
address@hidden
 On some platforms, this function returns nonsense values for
 unsupported arguments (like @math{2^56}), rather than failing:
 FreeBSD 10.
diff --git a/doc/posix-functions/localtime_r.texi 
b/doc/posix-functions/localtime_r.texi
index 6ca2aed6c..4862cbfd6 100644
--- a/doc/posix-functions/localtime_r.texi
+++ b/doc/posix-functions/localtime_r.texi
@@ -22,7 +22,13 @@ HP-UX 10.
 
 Portability problems not fixed by Gnulib:
 @itemize
address@hidden On some platforms, this function returns nonsense values for
address@hidden
+On some platforms, this function loops forever for values
+near extrema (such as the year @math{-2**31}):
+Mac OS X 10.6.
+You can use the @code{time_rz} module to work around the problem.
address@hidden
+On some platforms, this function returns nonsense values for
 unsupported arguments (like @math{2^56}), rather than failing:
 FreeBSD 10.
 @end itemize
diff --git a/lib/time_rz.c b/lib/time_rz.c
index 4682beb57..f9262c172 100644
--- a/lib/time_rz.c
+++ b/lib/time_rz.c
@@ -286,6 +286,21 @@ revert_tz (timezone_t tz)
 struct tm *
 localtime_rz (timezone_t tz, time_t const *t, struct tm *tm)
 {
+#ifdef HAVE_LOCALTIME_INFLOOP_BUG
+  /* The -67768038400665599 comes from:
+     https://lists.gnu.org/r/bug-gnulib/2017-07/msg00142.html
+     On affected platforms the greatest POSIX-compatible time_t value
+     that could return nonnull is 67768036191766798 (when
+     TZ="XXX24:59:59" it resolves to the year 2**31 - 1 + 1900, on
+     12-31 at 23:59:59), so test for that too while we're in the
+     neighborhood.  */
+  if (! (-67768038400665599 <= *t && *t <= 67768036191766798))
+    {
+      errno = EOVERFLOW;
+      return NULL;
+    }
+#endif
+
   if (!tz)
     return gmtime_r (t, tm);
   else
diff --git a/m4/time_rz.m4 b/m4/time_rz.m4
index 437814897..af9fa02b5 100644
--- a/m4/time_rz.m4
+++ b/m4/time_rz.m4
@@ -13,6 +13,38 @@ AC_DEFUN([gl_TIME_RZ],
   AC_REQUIRE([gl_HEADER_TIME_H_DEFAULTS])
   AC_REQUIRE([AC_STRUCT_TIMEZONE])
 
+  # Mac OS X 10.6 loops forever with some time_t values less
+  # than -67768038400665599.  See Bug#27706, Bug#27736, and
+  # https://lists.gnu.org/r/bug-gnulib/2017-07/msg00142.html
+  AC_CACHE_CHECK([whether localtime loops forever near extrema],
+    [gl_cv_func_localtime_infloop_bug],
+    [gl_cv_func_localtime_infloop_bug=no
+     AC_RUN_IFELSE(
+       [AC_LANG_PROGRAM(
+          [[#include <stdlib.h>
+            #include <string.h>
+            #include <unistd.h>
+            #include <time.h>
+          ]], [[
+            time_t t = -67768038400665600;
+            struct tm *tm;
+            char *tz = getenv ("TZ");
+            if (! (tz && strcmp (tz, "QQQ0") == 0))
+              return 0;
+            alarm (2);
+            tm = localtime (&t);
+            /* Use TM and *TM to suppress over-optimization.  */
+            return tm && tm->tm_isdst;
+          ]])],
+       [TZ=QQQ0 ./conftest$EXEEXT || gl_cv_func_localtime_infloop_bug=yes],
+       [],
+       [gl_cv_func_localtime_infloop_bug="guessing no"])])
+  if test "$gl_cv_func_localtime_infloop_bug" = yes; then
+      AC_DEFINE([HAVE_LOCALTIME_INFLOOP_BUG], 1,
+        [Define if localtime-like functions can loop forever on
+         extreme arguments.])
+  fi
+
   AC_CHECK_TYPES([timezone_t], [], [], [[#include <time.h>]])
   if test "$ac_cv_type_timezone_t" = yes; then
     HAVE_TIMEZONE_T=1
-- 
2.14.3




reply via email to

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