On Thu, 16 Nov 2017, Martin Storsjö wrote:

On Thu, 16 Nov 2017, Jacek Caban wrote:

On 16.11.2017 14:40, Martin Storsjö wrote:
On Thu, 16 Nov 2017, Jacek Caban wrote:

Hi Martin,

On 15.11.2017 21:06, Martin Storsjö wrote:
diff --git a/mingw-w64-crt/crt/ucrtbase_compat.c
b/mingw-w64-crt/crt/ucrtbase_compat.c
index c02c476..4f840ea 100644
--- a/mingw-w64-crt/crt/ucrtbase_compat.c
+++ b/mingw-w64-crt/crt/ucrtbase_compat.c
@@ -24,6 +24,7 @@
 #include <internal.h>
 #include <sect_attribs.h>
 #include <stdio.h>
+#include <time.h>

 #undef vfprintf
 #undef fprintf
@@ -137,6 +138,13 @@ int * __MINGW_IMP_SYMBOL(_fmode) = &local_fmode;
 char ** __MINGW_IMP_SYMBOL(_acmdln);
 char ** __MINGW_IMP_SYMBOL(_wcmdln);

+// These are required to provide the unrepfixed data symbols
"timezone"
+// and "tzname"; we can't remap "timezone" via a define due to clashes
+// with e.g. "struct timezone". We set these on startup, but they
won't
+// track changes during runtime.
+char** __MINGW_IMP_SYMBOL(tzname);
+static long local_timezone;
+long * __MINGW_IMP_SYMBOL(timezone) = &local_timezone;


 // The parts below are mostly ugly workarounds, necessary to
appease code
@@ -156,6 +164,9 @@ static void __cdecl init_compat_dtor(void)
   InitializeCriticalSection(&exit_lock);

   atexit(free_locks);
+
+  __MINGW_IMP_SYMBOL(tzname) = _tzname;
+  local_timezone = _timezone;


I'd prefer a different solution, ideally not touching initialization
code that's used for all binaries, even those not needing it at all.


How about hooking _tzset instead? It could call ucrtbase _tzset and then
update our exported symbol. It's not perfect, but I think it would
behave slightly better (it will update in the most obvious case; I don't
think we want to hook more functions) and not affect initialization
code.

Wouldn't that still require getting the initial value at startup, in
case nobody ever calls _tzset?

Is it really a problem? My Linux that glibc also returns 0 unless I call
tzset first, msvcrt.dll returns 28800 constant until _tzset is called.

Oh, ok - in that case, getting the initial value doesn't make much sense no.

In this case, since MSVC dropped support for timezone, it's something we
can't support 100% correctly in any case. The remaining problem of
hooking solution is not the initial value, but the fact that some other
functions should update it as well.


The problem with hooking function calls is that this hooking and local
storage only is within the statically linked object files in
libucrtbase.a. Consider you're building two DLLs; each of them will
get a separate copy of the global variables that keep a cache of the
latest set state - only the one that actually calls _tzset will get
the updated value.

Sure, that's one of limitations. No matter what hack we choose, it will
always be a hack. As I mentioned earlier, we'd ideally just drop it as
well, but apparently we need some compat hack. We add that behind a huge
warning and any application willing to behave properly should be ported
use _get_timezone() anyway.

Yup - as with all other things, it's a tradeoff between making as much of existing mingw-compatible code build with as little modifications as possible, and making it do the right thing.

Anyway, as you said that the initial value doesn't make much sense, I can try to update this to not do anything at startup, and hook _tzset as you suggested, and adjust the deprecation warning messages accoringly.

Updated patch sent - after reading "man timezone" this makes much more sense.

// Martin
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to