On 2017-12-15 01:37, Steve Summit wrote:
There's code in tzcode (and, I suspect not coincidentally, glibc's localtime implementation as well) to not call the internal version of tzset on calls to localtime_r, but rather only on calls to localtime. The justification is that Posix says localtime_r doesn't need to update the global tzname variable.
I don't have a copy of the Posix spec handy, so I can't check: does Posix also say that localtime_r doesn't need to check for and make use of a possibly-changed value of TZ? As implemented (both in tzcode and glibc), it doesn't. If a program calls localtime, then calls setenv to set a new value of TZ, then calls localtime again, it works as expected, but if it calls localtime_r, setenv, localtime_r, it doesn't. (The workaround, of course, is to call localtime_r, setenv, tzset, localtime_r.)
Looks like localtime() SHALL but localtime_r() MAY set timezone information as if by calling tzset(); from https://publications.opengroup.org/t101: localtime|_r(): "[CX] [Option Start] Local timezone information is used as though localtime() calls tzset(). ... Unlike localtime(), the localtime_r() function is not required to set tzname. If localtime_r() sets tzname, it shall also set daylight and timezone. If localtime_r() does not set tzname, it shall not set daylight and shall not set timezone. [Option End]" tzset(): "APPLICATION USAGE Since the ctime(), localtime(), mktime(), strftime(), and strftime_l() functions are required to set timezone information as if by calling tzset(), there is no need for an explicit tzset() call before using these functions. *However, portable applications should call tzset() explicitly before using ctime_r() or localtime_r() because setting timezone information is optional for those functions.*" [My *emphasis*] I no longer have any copies of ISO/IEC 9899:1999[2007] C as referenced by POSIX 2008, but 9899:2011[2012] still does not include tzset(), so all aspects of local and daylight saving time determination are still implementation defined. Normative Annex K "Bounds-checking interfaces" section K.3.8 defines a localtime_s() function which appears identical to localtime_r(), and other ..._s suffixed functions enabled by defining __STDC_LIB_EXT1__ like POSIX ..._r suffixed functions, without any additional requirements. -- Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada