global 'timezone' on x32
localtime.c defines 'timezone' as a time_t. glibc (which doesn't use tzcode) and bionic (which does) currently declare 'timezone' as a long int. POSIX also says 'long'. the mismatch causes trouble on x32. --elliott
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@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
thanks. i've brought Android up to date with tzcode2013f: https://android-review.googlesource.com/#/c/66521/ On Tue, Sep 24, 2013 at 6:45 PM, Paul Eggert <eggert@cs.ucla.edu> wrote:
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@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
participants (2)
-
enh -
Paul Eggert