summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2021-02-23 07:23:29 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2021-02-23 07:23:29 (GMT)
commit8242d1a544d685846fe49557be8c9fd628d42329 (patch)
tree1f426b6cd5ab89ab92e196d98f08898aa6866c89
parent7bfe776283e21b9f434c9b47c2ac37b8451f41e8 (diff)
downloadtcl-8242d1a544d685846fe49557be8c9fd628d42329.zip
tcl-8242d1a544d685846fe49557be8c9fd628d42329.tar.gz
tcl-8242d1a544d685846fe49557be8c9fd628d42329.tar.bz2
Use _wgetenv() in stead of getenv() on Windows: The wide environment is not always well-synchonized with the locale environment. Problem detected on the sebres-8-6-clock-speedup-cr2, but this branch only exposed the bug, it did not cause it.
-rw-r--r--generic/tclBasic.c4
-rw-r--r--generic/tclClock.c44
-rw-r--r--generic/tclIOUtil.c11
-rw-r--r--library/clock.tcl3
4 files changed, 49 insertions, 13 deletions
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index 895d160..2f1819f 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -583,6 +583,10 @@ Tcl_CreateInterp(void)
Tcl_InitHashTable(&iPtr->packageTable, TCL_STRING_KEYS);
iPtr->packageUnknown = NULL;
+#ifdef _WIN32
+# define getenv(x) _wgetenv(L##x) /* On Windows, use _wgetenv below */
+#endif
+
/* TIP #268 */
if (getenv("TCL_PKG_PREFER_LATEST") == NULL) {
iPtr->packagePrefer = PKG_PREFER_STABLE;
diff --git a/generic/tclClock.c b/generic/tclClock.c
index 2c5173a..ca1df44 100644
--- a/generic/tclClock.c
+++ b/generic/tclClock.c
@@ -1650,20 +1650,37 @@ ClockGetenvObjCmd(
int objc,
Tcl_Obj *const objv[])
{
+#ifdef _WIN32
+ const WCHAR *varName;
+ const WCHAR *varValue;
+ Tcl_DString ds;
+#else
const char *varName;
const char *varValue;
+#endif
(void)clientData;
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "name");
return TCL_ERROR;
}
+#ifdef _WIN32
+ varName = (const WCHAR *)Tcl_WinUtfToTChar(TclGetString(objv[1]), -1, &ds);
+ varValue = _wgetenv(varName);
+ Tcl_DStringFree(&ds);
+ if (varValue == NULL) {
+ varValue = L"";
+ }
+ Tcl_WinTCharToUtf((TCHAR *)varValue, -1, &ds);
+ Tcl_DStringResult(interp, &ds);
+#else
varName = TclGetString(objv[1]);
varValue = getenv(varName);
if (varValue == NULL) {
varValue = "";
}
Tcl_SetObjResult(interp, Tcl_NewStringObj(varValue, -1));
+#endif
return TCL_OK;
}
@@ -2026,15 +2043,24 @@ ClockSecondsObjCmd(
*----------------------------------------------------------------------
*/
+#ifdef _WIN32
+#define getenv(x) _wgetenv(L##x)
+#else
+#define WCHAR char
+#define wcslen strlen
+#define wcscmp strcmp
+#define wcscpy strcpy
+#endif
+
static void
TzsetIfNecessary(void)
{
- static char *tzWas = (char *)INT2PTR(-1); /* Previous value of TZ, protected by
- * clockMutex. */
+ static WCHAR* tzWas = (WCHAR *)INT2PTR(-1); /* Previous value of TZ, protected by
+ * clockMutex. */
static long tzLastRefresh = 0; /* Used for latency before next refresh */
static size_t tzEnvEpoch = 0; /* Last env epoch, for faster signaling,
that TZ changed via TCL */
- const char *tzIsNow; /* Current value of TZ */
+ const WCHAR *tzIsNow; /* Current value of TZ */
/*
* Prevent performance regression on some platforms by resolving of system time zone:
@@ -2052,17 +2078,17 @@ TzsetIfNecessary(void)
Tcl_MutexLock(&clockMutex);
tzIsNow = getenv("TZ");
- if (tzIsNow != NULL && (tzWas == NULL || tzWas == (char*)INT2PTR(-1)
- || strcmp(tzIsNow, tzWas) != 0)) {
+ if (tzIsNow != NULL && (tzWas == NULL || tzWas == (WCHAR *)INT2PTR(-1)
+ || wcscmp(tzIsNow, tzWas) != 0)) {
tzset();
- if (tzWas != NULL && tzWas != (char*)INT2PTR(-1)) {
+ if (tzWas != NULL && tzWas != (WCHAR *)INT2PTR(-1)) {
ckfree(tzWas);
}
- tzWas = (char *)ckalloc(strlen(tzIsNow) + 1);
- strcpy(tzWas, tzIsNow);
+ tzWas = (WCHAR *)ckalloc(sizeof(WCHAR) * (wcslen(tzIsNow) + 1));
+ wcscpy(tzWas, tzIsNow);
} else if (tzIsNow == NULL && tzWas != NULL) {
tzset();
- if (tzWas != (char*)INT2PTR(-1)) ckfree(tzWas);
+ if (tzWas != (WCHAR *)INT2PTR(-1)) ckfree(tzWas);
tzWas = NULL;
}
Tcl_MutexUnlock(&clockMutex);
diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c
index 5566f3e..312fd08 100644
--- a/generic/tclIOUtil.c
+++ b/generic/tclIOUtil.c
@@ -3158,6 +3158,13 @@ Tcl_FSLoadFile(
* present and set to true (any integer > 0) then the unlink is skipped.
*/
+#ifdef _WIN32
+#define getenv(x) _wgetenv(L##x)
+#define atoi(x) _wtoi(x)
+#else
+#define WCHAR char
+#endif
+
static int
skipUnlink (Tcl_Obj* shlibFile)
{
@@ -3178,9 +3185,9 @@ skipUnlink (Tcl_Obj* shlibFile)
#ifdef hpux
return 1;
#else
- char* skipstr;
+ WCHAR *skipstr;
- skipstr = getenv ("TCL_TEMPLOAD_NO_UNLINK");
+ skipstr = getenv("TCL_TEMPLOAD_NO_UNLINK");
if (skipstr && (skipstr[0] != '\0')) {
return atoi(skipstr);
}
diff --git a/library/clock.tcl b/library/clock.tcl
index 273b534..aa5d228 100644
--- a/library/clock.tcl
+++ b/library/clock.tcl
@@ -2988,8 +2988,7 @@ proc ::tcl::clock::GetSystemTimeZone {} {
set timezone $result
} elseif {[set result [getenv TZ]] ne {}} {
set timezone $result
- }
- if {![info exists timezone]} {
+ } else {
# Cache the time zone only if it was detected by one of the
# expensive methods.
if { [info exists CachedSystemTimeZone] } {