[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
tzset: add native Windows workaround
From: |
Bruno Haible |
Subject: |
tzset: add native Windows workaround |
Date: |
Mon, 01 May 2017 18:40:53 +0200 |
User-agent: |
KMail/5.1.3 (Linux/4.4.0-75-generic; KDE/5.18.0; x86_64; ; ) |
> * Some which should obey TZ, just that they should ignore the values set by
> Cygwin (instead of exhibiting garbage behaviour):
>
> _tzset
> https://msdn.microsoft.com/en-us/library/aa273389.aspx
> https://msdn.microsoft.com/en-us/library/90s5c885.aspx
> http://pubs.opengroup.org/onlinepubs/9699919799/functions/tzset.html
Here's the workaround for 'tzset'.
2017-05-01 Bruno Haible <address@hidden>
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/doc/posix-functions/tzset.texi b/doc/posix-functions/tzset.texi
index 30b147c..a457409 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.
address@hidden
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
address@hidden
-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/tzset.c b/lib/tzset.c
index 1cb9822..ce854b9 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/tzset.m4 b/m4/tzset.m4
index 20939e9..08362fe 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 e934d55..1bc29f4 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:
diff --git a/lib/time_rz.c b/lib/time_rz.c
index 82f3f3f..95c7293 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/m4/time_rz.m4 b/m4/time_rz.m4
index 79060e0..079e933 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 <time.h>]])
if test "$ac_cv_type_timezone_t" = yes; then
- tzset: add native Windows workaround,
Bruno Haible <=
- Re: tzset: add native Windows workaround, Paul Eggert, 2017/05/02
- Re: tzset: add native Windows workaround, Bruno Haible, 2017/05/02
- Re: tzset: add native Windows workaround, Paul Eggert, 2017/05/03
- Re: tzset: add native Windows workaround, Ken Brown, 2017/05/03
- Re: tzset: add native Windows workaround, Paul Eggert, 2017/05/03
- Re: tzset: add native Windows workaround, Marco Atzeri, 2017/05/03
- Re: tzset: add native Windows workaround, Ken Brown, 2017/05/03
- Re: tzset: add native Windows workaround, Bruno Haible, 2017/05/09
- Re: tzset: add native Windows workaround, Bruno Haible, 2017/05/09
- Re: tzset: add native Windows workaround, Eli Zaretskii, 2017/05/04