Mercurial > hg > octave-jordi > gnulib-hg
changeset 18065:fd4663ad7454
time_rz: port to Solaris etc.
Works around a tzname problem on platforms like Solaris that have
tzname but not tm_zone, by setting tzname at the appropriate time
and restoring it later.
* lib/time_rz.c (tzname_address, tzname_value) [HAVE_TZNAME]:
New static vars.
(save_abbr) [HAVE_TZNAME]: Set them.
(revert_tz) [HAVE_TZNAME]: Clear or use them.
(restore_tzname): New function.
(localtime_rz, mktime_z): Use it.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Sat, 25 Jul 2015 15:20:10 -0700 |
parents | e848c8248a0b |
children | fc4efc29b92e |
files | ChangeLog lib/time_rz.c |
diffstat | 2 files changed, 52 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,16 @@ 2015-07-25 Paul Eggert <eggert@cs.ucla.edu> + time_rz: port to Solaris etc. + Works around a tzname problem on platforms like Solaris that have + tzname but not tm_zone, by setting tzname at the appropriate time + and restoring it later. + * lib/time_rz.c (tzname_address, tzname_value) [HAVE_TZNAME]: + New static vars. + (save_abbr) [HAVE_TZNAME]: Set them. + (revert_tz) [HAVE_TZNAME]: Clear or use them. + (restore_tzname): New function. + (localtime_rz, mktime_z): Use it. + time_rz: now LGPL * modules/time_rz (License): Now LGPL, because strftime depends on it.
--- a/lib/time_rz.c +++ b/lib/time_rz.c @@ -130,8 +130,19 @@ return tz; } +#if HAVE_TZNAME +/* If TZNAME_ADDRESS is nonnull, an assignment of a saved abbreviation. + TZNAME_ADDRESS should be either null, or &tzname[0], or &tzname[1]. + *TZNAME_ADDRESS = TZNAME_VALUE should be done after revert_tz + (indirectly) calls tzset, so that revert_tz can overwrite tzset's + assignment to tzname. Also, it should be done at the start of + the next localtime_tz or mktime_z, to undo the overwrite. */ +static char **tzname_address; +static char *tzname_value; +#endif + /* Save into TZ any nontrivial time zone abbreviation used by TM, - and update *TM or tzname if they point to the abbreviation. + and update *TM (or prepare to update tzname) if they use the abbreviation. Return true if successful, false (setting errno) otherwise. */ static bool save_abbr (timezone_t tz, struct tm *tm) @@ -189,8 +200,8 @@ tm->tm_zone = zone_copy; # endif # if HAVE_TZNAME - if (tzname_zone) - *tzname_zone = zone_copy; + tzname_address = tzname_zone; + tzname_value = zone_copy; # endif #endif return true; @@ -281,16 +292,41 @@ bool ok = change_env (tz); if (!ok) saved_errno = errno; +#if HAVE_TZNAME + if (!ok) + tzname_address = NULL; + if (tzname_address) + { + char *old_value = *tzname_address; + *tzname_address = tzname_value; + tzname_value = old_value; + } +#endif tzfree (tz); errno = saved_errno; return ok; } } +/* Restore an old tzname setting that was temporarily munged by revert_tz. */ +static void +restore_tzname (void) +{ +#if HAVE_TZNAME + if (tzname_address) + { + *tzname_address = tzname_value; + tzname_address = NULL; + } +#endif +} + /* Use time zone TZ to compute localtime_r (T, TM). */ struct tm * localtime_rz (timezone_t tz, time_t const *t, struct tm *tm) { + restore_tzname (); + if (!tz) return gmtime_r (t, tm); else @@ -312,6 +348,8 @@ time_t mktime_z (timezone_t tz, struct tm *tm) { + restore_tzname (); + if (!tz) return timegm (tm); else