[tz] global 'timezone' on x32

Paul Eggert eggert at cs.ucla.edu
Wed Sep 25 01:45:02 UTC 2013


Thanks, good catch.  'altzone' too.  These variables were
changed from 'long' to 'time_t' back in 1987, but (as you note)
that's incompatible with common practice on the rare hosts where
time_t is not 'long', so we should change them back, as follows
(pushed into the experimental repository on Github):

>From 6e770de05814b2fec6bc54bc0bace0d7f431fa04 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert at cs.ucla.edu>
Date: Tue, 24 Sep 2013 18:42:34 -0700
Subject: [PATCH] Port to x32 by fixing type incompatibility with POSIX.

Reported by Elliott Hughes in
<http://mm.icann.org/pipermail/tz/2013-September/020376.html>.
* localtime.c (timezone) [USG_COMPAT]:
(altzone) [ALTZONE]: Now long, not time_t.
* strftime.c (_fmt): Use long, not int, to store timezone.
* NEWS: Document this.
---
 NEWS        | 10 ++++++++++
 localtime.c |  4 ++--
 strftime.c  |  2 +-
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index c1e8ba3..355aea6 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,16 @@ Unreleased, experimental changes
 
     Palestine will fall back at 00:00, not 01:00.  (Thanks to Steffen Thorsen.)
 
+  Changes affecting API
+
+    The types of the global variables 'timezone' and 'altzone' (if present)
+    have been changed back to 'long'.  This is required for 'timezone'
+    by POSIX, and for 'altzone' by common practice, e.g., Solaris 11.
+    These variables were originally 'long' in the tz code, but were
+    mistakenly changed to 'time_t' in 1987; nobody reported the
+    incompatibility until now.  The difference matters on x32, where
+    'long' is 32 bits and 'time_t' is 64.  (Thanks to Elliott Hughes.)
+
   Changes affecting the build procedure
 
     Avoid long strings in leapseconds.awk to work around a mawk bug.
diff --git a/localtime.c b/localtime.c
index f2004b5..8c8edf3 100644
--- a/localtime.c
+++ b/localtime.c
@@ -215,12 +215,12 @@ char *			tzname[2] = {
 static struct tm	tm;
 
 #ifdef USG_COMPAT
-time_t			timezone = 0;
+long			timezone = 0;
 int			daylight = 0;
 #endif /* defined USG_COMPAT */
 
 #ifdef ALTZONE
-time_t			altzone = 0;
+long			altzone = 0;
 #endif /* defined ALTZONE */
 
 static int_fast32_t
diff --git a/strftime.c b/strftime.c
index aba3d33..c324f1b 100644
--- a/strftime.c
+++ b/strftime.c
@@ -492,7 +492,7 @@ label:
 				continue;
 			case 'z':
 				{
-				int		diff;
+				long		diff;
 				char const *	sign;
 
 				if (t->tm_isdst < 0)
-- 
1.8.1.2




More information about the tz mailing list