Subject: Re: OSX 10.6.8: Building from master branch fails.

From: Paul Eggert <[email-masked]>
Date: Tue, 27 Mar 2018 14:19:22 -0700

> >     (<= m -1034058203136)
> >     (<= m -1034058203135))
Unfortunately these numbers don't fit into a 30-bit integer and so they 
run afoul of a portability issue, namely, that files byte-compiled on a 
64-bit Emacs should run on a 32-bit Emacs and vice versa. I noticed this 
problem when preparing a patch to catch this sort of issue. To fix this 
particular instance of the problem, I attempted to migrate the localtime 
workaround into editfns.c (so that the fix is more-general, and is not 
limited to org-clock), by installing the attached patches into master. 
Please give them a try, since I don't have easy access to Mac OS X. I'm 
still a bit fuzzy on exactly which timestamps cause Mac OS X localtime 
to go belly-up (is it timezone dependent?), so quite possibly the magic 
numbers in these patches need to be adjusted a bit so that the code will 
work in any timezone from TZ=AAA-24:59:59 to TZ=ZZZ24:59:59; please let 
me know.

>From 72fad885b68617db85901a8e810211b557a31f99 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Tue, 27 Mar 2018 13:30:50 -0700
Subject: [PATCH 1/2] Update from Gnulib

This incorporates:
2018-03-26 time_rz: work around Mac OS X 10.6 infloop
2018-03-20 euidaccess: Port to native Windows.
* lib/euidaccess.c, lib/time_rz.c, m4/time_rz.m4: Copy from Gnulib.
---
 lib/euidaccess.c | 11 ++++++++---
 lib/time_rz.c    | 15 +++++++++++++++
 m4/time_rz.m4    | 32 ++++++++++++++++++++++++++++++++
 3 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/lib/euidaccess.c b/lib/euidaccess.c
index aee693571c..4f512f5af5 100644
--- a/lib/euidaccess.c
+++ b/lib/euidaccess.c
@@ -29,8 +29,11 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
-
-#include "root-uid.h"
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+# include <io.h>
+#else
+# include "root-uid.h"
+#endif
 
 #if HAVE_LIBGEN_H
 # include <libgen.h>
@@ -84,7 +87,9 @@ euidaccess (const char *file, int mode)
   return accessx (file, mode, ACC_SELF);
 #elif HAVE_EACCESS                      /* FreeBSD */
   return eaccess (file, mode);
-#else       /* Mac OS X, NetBSD, OpenBSD, HP-UX, Solaris, Cygwin, mingw, BeOS */
+#elif (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__  /* mingw */
+  return _access (file, mode);
+#else              /* Mac OS X, NetBSD, OpenBSD, HP-UX, Solaris, Cygwin, BeOS */
 
   uid_t uid = getuid ();
   gid_t gid = getgid ();
diff --git a/lib/time_rz.c b/lib/time_rz.c
index c1eca888f2..5293c7cf8d 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 4378148978..af9fa02b57 100644
--- a/m4/time_rz.m4
+++ b/m4/time_rz.m4
@@ -13,6 +13,38 @@ AC_DEFUN
   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

>From c8e8d16810ec09139c560c77572d3372a2edd8d2 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Tue, 27 Mar 2018 13:48:13 -0700
Subject: [PATCH 2/2] Avoid using unportable integer in org-clock

* lisp/org/org-clock.el (org-clock--oldest-date): Avoid use of an
integer outside portable Emacs range.  Go back to using a simple
check, since decode-time should no longer infloop.
---
 lisp/org/org-clock.el | 12 +-----------
 1 file changed, 1 insertion(+), 11 deletions(-)

diff --git a/lisp/org/org-clock.el b/lisp/org/org-clock.el
index 4c5fcc64b0..c124abd391 100644
--- a/lisp/org/org-clock.el
+++ b/lisp/org/org-clock.el
@@ -478,17 +478,7 @@ org-clock--oldest-date
 	  (funcall dichotomy
 		   most-negative-fixnum
 		   0
-		   (lambda (m)
-                     ;; libc in macOS 10.6 hangs when decoding times
-                     ;; around year -2**31.  Limit `high' not to go
-                     ;; any earlier than that.
-                     (unless (and (eq system-type 'darwin)
-                                  (string-match-p
-                                   "10\\.6\\.[[:digit:]]"
-                                   (shell-command-to-string
-                                    "sw_vers -productVersion"))
-                                  (<= m -1034058203135))
-                       (ignore-errors (decode-time (list m 0)))))))
+		   (lambda (m) (ignore-errors (decode-time (list m 0))))))
 	 (low
 	  (funcall dichotomy
 		   most-negative-fixnum
-- 
2.14.3