From: Bruno Haible Date: Mon, 1 May 2017 15:27:53 +0000 (+0200) Subject: tzset: Work around TZ problem on native Windows. X-Git-Tag: v1.0~6211 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=210cb7a9fb5a917e99dcf8e42ac4147a2b81bb33;p=gnulib.git tzset: Work around TZ problem on native Windows. * m4/tzset.m4 (gl_FUNC_TZSET): Require AC_CANONICAL_HOST. On native Windows, set REPLACE_TZSET to 1. * lib/tzset.c (tzset): On native Windows, fix TZ if necessary, and invoke '_tzset' instead of 'tzset'. * doc/posix-functions/tzset.texi: Mention the native Windows workaround. * modules/time_rz (Depends-on): Add tzset. * lib/time_rz.c (tzset): Remove fallback definition. * m4/time_rz.m4 (gl_TIME_RZ): Don't test for tzset. --- diff --git a/ChangeLog b/ChangeLog index bafd2eb2e6..64231468b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2017-05-01 Bruno Haible + + tzset: Work around TZ problem on native Windows. + * m4/tzset.m4 (gl_FUNC_TZSET): Require AC_CANONICAL_HOST. On native + Windows, set REPLACE_TZSET to 1. + * lib/tzset.c (tzset): On native Windows, fix TZ if necessary, and + invoke '_tzset' instead of 'tzset'. + * doc/posix-functions/tzset.texi: Mention the native Windows workaround. + + * modules/time_rz (Depends-on): Add tzset. + * lib/time_rz.c (tzset): Remove fallback definition. + * m4/time_rz.m4 (gl_TIME_RZ): Don't test for tzset. + 2017-05-01 Bruno Haible mktime: Fix dependencies. diff --git a/doc/posix-functions/tzset.texi b/doc/posix-functions/tzset.texi index 30b147cc3c..a457409352 100644 --- a/doc/posix-functions/tzset.texi +++ b/doc/posix-functions/tzset.texi @@ -9,6 +9,9 @@ Gnulib module: tzset Portability problems fixed by Gnulib: @itemize @item +On native Windows platforms (mingw, MSVC), this function works incorrectly +when the environment variable @code{TZ} has been set by Cygwin. +@item This function clobbers the buffer used by the localtime function on some platforms: Solaris 2.6. @@ -16,7 +19,4 @@ Solaris 2.6. Portability problems not fixed by Gnulib: @itemize -@item -On native Windows platforms (mingw, MSVC), this function works incorrectly -when the environment variable @code{TZ} has been set by Cygwin. @end itemize diff --git a/lib/time_rz.c b/lib/time_rz.c index 82f3f3f19d..95c7293fef 100644 --- a/lib/time_rz.c +++ b/lib/time_rz.c @@ -40,10 +40,6 @@ # define SIZE_MAX ((size_t) -1) #endif -#if !HAVE_TZSET -static void tzset (void) { } -#endif - /* The approximate size to use for small allocation requests. This is the largest "small" request for the GNU C library malloc. */ enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 }; diff --git a/lib/tzset.c b/lib/tzset.c index 1cb9822146..ce854b9f11 100644 --- a/lib/tzset.c +++ b/lib/tzset.c @@ -40,7 +40,23 @@ tzset (void) struct tm save = *localtime_buffer_addr; #endif +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + /* If the environment variable TZ has been set by Cygwin, neutralize it. + The Microsoft CRT interprets TZ differently than Cygwin and produces + incorrect results if TZ has the syntax used by Cygwin. */ + const char *tz = getenv ("TZ"); + if (tz != NULL && strchr (tz, '/') != NULL) + _putenv ("TZ="); + + /* On native Windows, tzset() is deprecated. Use _tzset() instead. See + https://msdn.microsoft.com/en-us/library/ms235451.aspx + https://msdn.microsoft.com/en-us/library/90s5c885.aspx */ + _tzset (); +#elif HAVE_TZSET tzset (); +#else + /* Do nothing. Avoid infinite recursion. */ +#endif #if TZSET_CLOBBERS_LOCALTIME *localtime_buffer_addr = save; diff --git a/m4/time_rz.m4 b/m4/time_rz.m4 index 79060e00fc..079e933b4e 100644 --- a/m4/time_rz.m4 +++ b/m4/time_rz.m4 @@ -12,7 +12,6 @@ AC_DEFUN([gl_TIME_RZ], AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) AC_REQUIRE([gl_HEADER_SYS_TIME_H_DEFAULTS]) AC_REQUIRE([AC_STRUCT_TIMEZONE]) - AC_CHECK_FUNCS_ONCE([tzset]) AC_CHECK_TYPES([timezone_t], [], [], [[#include ]]) if test "$ac_cv_type_timezone_t" = yes; then diff --git a/m4/tzset.m4 b/m4/tzset.m4 index 20939e9b6a..08362fea73 100644 --- a/m4/tzset.m4 +++ b/m4/tzset.m4 @@ -17,11 +17,13 @@ AC_DEFUN([gl_FUNC_TZSET], [ AC_REQUIRE([gl_HEADER_TIME_H_DEFAULTS]) AC_REQUIRE([gl_LOCALTIME_BUFFER_DEFAULTS]) + AC_REQUIRE([AC_CANONICAL_HOST]) AC_CHECK_FUNCS_ONCE([tzset]) if test $ac_cv_func_tzset = no; then HAVE_TZSET=0 fi gl_FUNC_TZSET_CLOBBER + REPLACE_TZSET=0 case "$gl_cv_func_tzset_clobber" in *yes) REPLACE_TZSET=1 @@ -29,9 +31,9 @@ AC_DEFUN([gl_FUNC_TZSET], [Define if tzset clobbers localtime's static buffer.]) gl_LOCALTIME_BUFFER_NEEDED ;; - *) - REPLACE_TZSET=0 - ;; + esac + case "$host_os" in + mingw*) REPLACE_TZSET=1 ;; esac ]) diff --git a/modules/time_rz b/modules/time_rz index e934d55720..1bc29f401f 100644 --- a/modules/time_rz +++ b/modules/time_rz @@ -24,6 +24,7 @@ setenv [test "$HAVE_TIMEZONE_T" = 0] stdbool [test "$HAVE_TIMEZONE_T" = 0] time_r [test "$HAVE_TIMEZONE_T" = 0] timegm [test "$HAVE_TIMEZONE_T" = 0] +tzset [test "$HAVE_TIMEZONE_T" = 0] unsetenv [test "$HAVE_TIMEZONE_T" = 0] configure.ac: