[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: MinGW-related patches that were reported in 2014 but not applied

From: Eli Zaretskii
Subject: Re: MinGW-related patches that were reported in 2014 but not applied
Date: Sun, 24 Jul 2016 18:10:36 +0300

> From: Andy Wingo <address@hidden>
> Cc: address@hidden
> Date: Sat, 23 Jul 2016 22:36:17 +0200
> >> > * libguile/stime.c (scm_strftime) [__MINGW32__]: Don't use the
> >> > trick of appending "0" to the time-zone string, Windows runtime
> >> > doesn't support that.
> >> > +#ifndef __MINGW32__
> >> > +    /* Don't do this for MinGW: it only supports fixed-format
> >> > +       TTTnnnDDD TZ specifications, and gets confused if a zero is
> >> > +       appended.  */
> >> 
> >> This patch disables the setzone() call entirely; seems to be the wrong
> >> thing, given that MinGW doesn't appear to have struct tm->tm_zone.  What
> >> if we just disable appending the 0 to the time zone?
> >
> > I'm not sure I understand what you have in mind, but if you show a
> > patch and a simple test, I can run it here.
> The current code:
>     #if !defined (HAVE_STRUCT_TM_TM_ZONE)
>         /* it seems the only way to tell non-GNU versions of strftime what
>            zone to use (for the %Z format) is to set TZ in the
>            environment.  interrupts and thread switching must be deferred
>            until TZ is restored.  */
>         char **oldenv = NULL;
>         SCM zone_spec = SCM_SIMPLE_VECTOR_REF (stime, 10);
>         int have_zone = 0;
>         if (scm_is_true (zone_spec) && scm_c_string_length (zone_spec) > 0)
>           {
>         /* it's not required that the TZ setting be correct, just that
>            it has the right name.  so try something like TZ=EST0.
>            using only TZ=EST would be simpler but it doesn't work on
>            some OSs, e.g., Solaris.  */
>         SCM zone =
>           scm_string_append (scm_list_2 (zone_spec,
>                                          scm_from_locale_string ("0")));
>         have_zone = 1;
>         oldenv = setzone (zone, SCM_ARG2, FUNC_NAME);
>           }
>     #endif
> You said that appending the 0 confuses MinGW, so you skip this section
> and the corresponding one after the nstrftime.  But you're skipping the
> setzone too, so I don't see how the strftime tests would work.

Appending 0 confuses MinGW because time-zone strings on Windows can be
something like "Jerusalem Standard Time", in which case appending 0
will not DTRT.  If the TZ string is a 3-letter name like EST, then
EST0 will indeed work on Windows.

But what setzone does causes much more trouble: it replaces the
environ array with one that has a single variable TZ, and that
confuses the heck out of the Windows C runtime.  Windows programs
cannot run with an empty environ.

Frankly, I don't understand why all this stuff with setzone is needed,
because on Windows all that's required to do what I think this code is
trying to do is this:

  putenv ("TZ=whatever");
  tzset ();
  tm->tm_isdst = 0;

The last bit is required for when the "whatever" zone doesn't have a
DST name (like "EDT"), in which case %Z will produce an empty string.
The code already does call tzset, so it should simply call putenv and
set the isdst member, instead of using this strange method implemented
in setzone.  Am I missing something?

> According to POSIX, our TZ value is valid:
> What is the MinGW restriction?  You mention it in the comment but I
> don't understand the comment.

If you are asking about the forms of the TZ variable, they are
documented here:

But that's not the important problem with setzone.

Of course, the same problems exist with localtime and mktime: they
should also call putenv instead of setzone.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]