From 636f5e942c8f543e8aea00f83ffbfd1ec2d3fc91 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 26 Aug 2014 12:01:30 -0700 Subject: [PROPOSED PATCH 1/4] tzalloc(NULL) now acts like tzset() does when TZ is unset. Suggested by Jonathan Lennox in: http://mm.icann.org/pipermail/tz/2014-August/021529.html * localtime.c (tzalloc): Treat NULL argument like tzsetwall. (tzsetwall_unlocked): Remove, replacing with ... (tzsetlcl): New function, which merges the old tzsetwall and tzset_unlocked. (zoneinit): Treat a null NAME like tzsetwall. (tzsetwall, tzset_unlocked): Rewrite to use tzsetlcl. * NEWS: Document this. --- NEWS | 4 ++-- localtime.c | 73 ++++++++++++++++++++++++------------------------------------- 2 files changed, 30 insertions(+), 47 deletions(-) diff --git a/NEWS b/NEWS index b8ef455..db9e46f 100644 --- a/NEWS +++ b/NEWS @@ -58,8 +58,8 @@ Unreleased, experimental changes zones simultaneously, e.g., an application where each thread may be in a different time zone. The new functions are tzalloc, tzfree, localtime_rz, mktime_z, and (if STD_INSPIRED is also defined) - posix2time_z and time2posix_z. (Thanks to Alan Barrett for - helping to debug this.) + posix2time_z and time2posix_z. (Thanks to Alan Barrett and + Jonathan Lennox for helping to debug this.) The tz code now attempts to infer TM_GMTOFF and TM_ZONE if not already defined, to make it easier to configure on common platforms. diff --git a/localtime.c b/localtime.c index aee343e..e294a9e 100644 --- a/localtime.c +++ b/localtime.c @@ -1174,42 +1174,11 @@ gmtload(struct state *const sp) tzparse(gmt, sp, true); } -static void -tzsetwall_unlocked(void) -{ - if (lcl_is_set < 0) - return; -#ifdef ALL_STATE - if (! lclptr) - lclptr = malloc(sizeof *lclptr); -#endif - if (lclptr && ! tzload(NULL, lclptr, true)) - gmtload(lclptr); - settzname(); - lcl_is_set = -1; -} - -#ifdef STD_INSPIRED -void -tzsetwall(void) -{ - if (lock() != 0) - return; - tzsetwall_unlocked(); - unlock(); -} -#endif - static struct state * zoneinit(struct state *sp, char const *name) { if (sp) { - if (! name - || (name[0] - && ! (tzload(name, sp, true) - || (name[0] != ':' && tzparse(name, sp, false))))) - gmtload(sp); - else if (! name[0]) { + if (name && ! name[0]) { /* ** User wants it fast rather than right. */ @@ -1220,25 +1189,22 @@ zoneinit(struct state *sp, char const *name) sp->ttis[0].tt_gmtoff = 0; sp->ttis[0].tt_abbrind = 0; strcpy(sp->chars, gmt); - } + } else if (! (tzload(name, sp, true) + || (name && name[0] != ':' && tzparse(name, sp, false)))) + gmtload(sp); } return sp; } static void -tzset_unlocked(void) +tzsetlcl(char const *name) { - bool shortname; - register char const *name = getenv("TZ"); - - if (!name) { - tzsetwall_unlocked(); - return; - } - shortname = strlen(name) < sizeof lcl_TZname; - if (0 < lcl_is_set && strcmp(lcl_TZname, name) == 0) + int lcl = name ? strlen(name) < sizeof lcl_TZname : -1; + if (lcl < 0 + ? lcl_is_set < 0 + : 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0) return; - if (shortname) + if (0 < lcl) strcpy(lcl_TZname, name); #ifdef ALL_STATE if (! lclptr) @@ -1246,7 +1212,24 @@ tzset_unlocked(void) #endif /* defined ALL_STATE */ zoneinit(lclptr, name); settzname(); - lcl_is_set = shortname; + lcl_is_set = lcl; +} + +#ifdef STD_INSPIRED +void +tzsetwall(void) +{ + if (lock() != 0) + return; + tzsetlcl(NULL); + unlock(); +} +#endif + +static void +tzset_unlocked(void) +{ + return tzsetlcl(getenv("TZ")); } void -- 1.9.1