Import Tcl 8.6.11
This commit is contained in:
104
generic/tclEnv.c
104
generic/tclEnv.c
@@ -17,12 +17,31 @@
|
||||
|
||||
TCL_DECLARE_MUTEX(envMutex) /* To serialize access to environ. */
|
||||
|
||||
#if defined(_WIN32)
|
||||
# define tenviron _wenviron
|
||||
# define tenviron2utfdstr(tenvstr, len, dstr) \
|
||||
Tcl_WinTCharToUtf((TCHAR *)tenvstr, len, dstr)
|
||||
# define utf2tenvirondstr(str, len, dstr) \
|
||||
(const WCHAR *)Tcl_WinUtfToTChar(str, len, dstr)
|
||||
# define techar WCHAR
|
||||
# ifdef USE_PUTENV
|
||||
# define putenv(env) _wputenv((const wchar_t *)env)
|
||||
# endif
|
||||
#else
|
||||
# define tenviron environ
|
||||
# define tenviron2utfdstr(tenvstr, len, dstr) \
|
||||
Tcl_ExternalToUtfDString(NULL, tenvstr, len, dstr)
|
||||
# define utf2tenvirondstr(str, len, dstr) \
|
||||
Tcl_UtfToExternalDString(NULL, str, len, dstr)
|
||||
# define techar char
|
||||
#endif
|
||||
|
||||
static struct {
|
||||
int cacheSize; /* Number of env strings in cache. */
|
||||
char **cache; /* Array containing all of the environment
|
||||
* strings that Tcl has allocated. */
|
||||
#ifndef USE_PUTENV
|
||||
char **ourEnviron; /* Cache of the array that we allocate. We
|
||||
techar **ourEnviron; /* Cache of the array that we allocate. We
|
||||
* need to track this in case another
|
||||
* subsystem swaps around the environ array
|
||||
* like we do. */
|
||||
@@ -34,6 +53,8 @@ static struct {
|
||||
#endif
|
||||
} env;
|
||||
|
||||
#define tNTL sizeof(techar)
|
||||
|
||||
/*
|
||||
* Declarations for local functions defined in this file:
|
||||
*/
|
||||
@@ -106,6 +127,17 @@ TclSetupEnv(
|
||||
/*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
|
||||
TclFindArrayPtrElements(varPtr, &namesHash);
|
||||
|
||||
#if defined(_WIN32)
|
||||
if (tenviron == NULL) {
|
||||
/*
|
||||
* When we are started from main(), the _wenviron array could
|
||||
* be NULL and will be initialized by the first _wgetenv() call.
|
||||
*/
|
||||
|
||||
(void) _wgetenv(L"WINDIR");
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Go through the environment array and transfer its values into Tcl. At
|
||||
* the same time, remove those elements we add/update from the hash table
|
||||
@@ -113,17 +145,17 @@ TclSetupEnv(
|
||||
* will hold just the parts to remove.
|
||||
*/
|
||||
|
||||
if (environ[0] != NULL) {
|
||||
if (tenviron[0] != NULL) {
|
||||
int i;
|
||||
|
||||
Tcl_MutexLock(&envMutex);
|
||||
for (i = 0; environ[i] != NULL; i++) {
|
||||
for (i = 0; tenviron[i] != NULL; i++) {
|
||||
Tcl_Obj *obj1, *obj2;
|
||||
const char *p1;
|
||||
char *p2;
|
||||
|
||||
p1 = Tcl_ExternalToUtfDString(NULL, environ[i], -1, &envString);
|
||||
p2 = strchr(p1, '=');
|
||||
p1 = tenviron2utfdstr(tenviron[i], -1, &envString);
|
||||
p2 = (char *)strchr(p1, '=');
|
||||
if (p2 == NULL) {
|
||||
/*
|
||||
* This condition seem to happen occasionally under some
|
||||
@@ -172,7 +204,7 @@ TclSetupEnv(
|
||||
|
||||
for (hPtr=Tcl_FirstHashEntry(&namesHash, &search); hPtr!=NULL;
|
||||
hPtr=Tcl_NextHashEntry(&search)) {
|
||||
Tcl_Obj *elemName = Tcl_GetHashValue(hPtr);
|
||||
Tcl_Obj *elemName = (Tcl_Obj *)Tcl_GetHashValue(hPtr);
|
||||
|
||||
TclObjUnsetVar2(interp, varNamePtr, elemName, TCL_GLOBAL_ONLY);
|
||||
}
|
||||
@@ -219,7 +251,7 @@ TclSetEnv(
|
||||
unsigned nameLength, valueLength;
|
||||
int index, length;
|
||||
char *p, *oldValue;
|
||||
const char *p2;
|
||||
const techar *p2;
|
||||
|
||||
/*
|
||||
* Figure out where the entry is going to go. If the name doesn't already
|
||||
@@ -238,23 +270,23 @@ TclSetEnv(
|
||||
* environment is the one we allocated. [Bug 979640]
|
||||
*/
|
||||
|
||||
if ((env.ourEnviron != environ) || (length+2 > env.ourEnvironSize)) {
|
||||
char **newEnviron = ckalloc((length + 5) * sizeof(char *));
|
||||
if ((env.ourEnviron != tenviron) || (length+2 > env.ourEnvironSize)) {
|
||||
techar **newEnviron = (techar **)ckalloc((length + 5) * sizeof(techar *));
|
||||
|
||||
memcpy(newEnviron, environ, length * sizeof(char *));
|
||||
memcpy(newEnviron, tenviron, length * sizeof(techar *));
|
||||
if ((env.ourEnvironSize != 0) && (env.ourEnviron != NULL)) {
|
||||
ckfree(env.ourEnviron);
|
||||
}
|
||||
environ = env.ourEnviron = newEnviron;
|
||||
tenviron = (env.ourEnviron = newEnviron);
|
||||
env.ourEnvironSize = length + 5;
|
||||
}
|
||||
index = length;
|
||||
environ[index + 1] = NULL;
|
||||
tenviron[index + 1] = NULL;
|
||||
#endif /* USE_PUTENV */
|
||||
oldValue = NULL;
|
||||
nameLength = strlen(name);
|
||||
} else {
|
||||
const char *env;
|
||||
const char *oldEnv;
|
||||
|
||||
/*
|
||||
* Compare the new value to the existing value. If they're the same
|
||||
@@ -264,16 +296,16 @@ TclSetEnv(
|
||||
* interpreters.
|
||||
*/
|
||||
|
||||
env = Tcl_ExternalToUtfDString(NULL, environ[index], -1, &envString);
|
||||
if (strcmp(value, env + (length + 1)) == 0) {
|
||||
oldEnv = tenviron2utfdstr(tenviron[index], -1, &envString);
|
||||
if (strcmp(value, oldEnv + (length + 1)) == 0) {
|
||||
Tcl_DStringFree(&envString);
|
||||
Tcl_MutexUnlock(&envMutex);
|
||||
return;
|
||||
}
|
||||
Tcl_DStringFree(&envString);
|
||||
|
||||
oldValue = environ[index];
|
||||
nameLength = (unsigned) length;
|
||||
oldValue = (char *)tenviron[index];
|
||||
nameLength = length;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -283,18 +315,18 @@ TclSetEnv(
|
||||
*/
|
||||
|
||||
valueLength = strlen(value);
|
||||
p = ckalloc(nameLength + valueLength + 2);
|
||||
p = (char *)ckalloc(nameLength + valueLength + 2);
|
||||
memcpy(p, name, nameLength);
|
||||
p[nameLength] = '=';
|
||||
memcpy(p+nameLength+1, value, valueLength+1);
|
||||
p2 = Tcl_UtfToExternalDString(NULL, p, -1, &envString);
|
||||
p2 = utf2tenvirondstr(p, -1, &envString);
|
||||
|
||||
/*
|
||||
* Copy the native string to heap memory.
|
||||
*/
|
||||
|
||||
p = ckrealloc(p, Tcl_DStringLength(&envString) + 1);
|
||||
memcpy(p, p2, (unsigned) Tcl_DStringLength(&envString) + 1);
|
||||
p = (char *)ckrealloc(p, Tcl_DStringLength(&envString) + tNTL);
|
||||
memcpy(p, p2, Tcl_DStringLength(&envString) + tNTL);
|
||||
Tcl_DStringFree(&envString);
|
||||
|
||||
#ifdef USE_PUTENV
|
||||
@@ -305,7 +337,7 @@ TclSetEnv(
|
||||
putenv(p);
|
||||
index = TclpFindVariable(name, &length);
|
||||
#else
|
||||
environ[index] = p;
|
||||
tenviron[index] = (techar *)p;
|
||||
#endif /* USE_PUTENV */
|
||||
|
||||
/*
|
||||
@@ -314,7 +346,7 @@ TclSetEnv(
|
||||
* string in the cache.
|
||||
*/
|
||||
|
||||
if ((index != -1) && (environ[index] == p)) {
|
||||
if ((index != -1) && (tenviron[index] == (techar *)p)) {
|
||||
ReplaceString(oldValue, p);
|
||||
#ifdef HAVE_PUTENV_THAT_COPIES
|
||||
} else {
|
||||
@@ -379,7 +411,7 @@ Tcl_PutEnv(
|
||||
*/
|
||||
|
||||
name = Tcl_ExternalToUtfDString(NULL, assignment, -1, &nameString);
|
||||
value = strchr(name, '=');
|
||||
value = (char *)strchr(name, '=');
|
||||
|
||||
if ((value != NULL) && (value != name)) {
|
||||
value[0] = '\0';
|
||||
@@ -440,7 +472,7 @@ TclUnsetEnv(
|
||||
* Remember the old value so we can free it if Tcl created the string.
|
||||
*/
|
||||
|
||||
oldValue = environ[index];
|
||||
oldValue = (char *)tenviron[index];
|
||||
|
||||
/*
|
||||
* Update the system environment. This must be done before we update the
|
||||
@@ -454,20 +486,20 @@ TclUnsetEnv(
|
||||
*/
|
||||
|
||||
#if defined(_WIN32)
|
||||
string = ckalloc(length + 2);
|
||||
memcpy(string, name, (size_t) length);
|
||||
string = (char *)ckalloc(length + 2);
|
||||
memcpy(string, name, length);
|
||||
string[length] = '=';
|
||||
string[length+1] = '\0';
|
||||
#else
|
||||
string = ckalloc(length + 1);
|
||||
memcpy(string, name, (size_t) length);
|
||||
string = (char *)ckalloc(length + 1);
|
||||
memcpy(string, name, length);
|
||||
string[length] = '\0';
|
||||
#endif /* _WIN32 */
|
||||
|
||||
Tcl_UtfToExternalDString(NULL, string, -1, &envString);
|
||||
string = ckrealloc(string, Tcl_DStringLength(&envString) + 1);
|
||||
utf2tenvirondstr(string, -1, &envString);
|
||||
string = (char *)ckrealloc(string, Tcl_DStringLength(&envString) + tNTL);
|
||||
memcpy(string, Tcl_DStringValue(&envString),
|
||||
(unsigned) Tcl_DStringLength(&envString)+1);
|
||||
Tcl_DStringLength(&envString) + tNTL);
|
||||
Tcl_DStringFree(&envString);
|
||||
|
||||
putenv(string);
|
||||
@@ -478,7 +510,7 @@ TclUnsetEnv(
|
||||
* string in the cache.
|
||||
*/
|
||||
|
||||
if (environ[index] == string) {
|
||||
if (tenviron[index] == (techar *)string) {
|
||||
ReplaceString(oldValue, string);
|
||||
#ifdef HAVE_PUTENV_THAT_COPIES
|
||||
} else {
|
||||
@@ -490,7 +522,7 @@ TclUnsetEnv(
|
||||
#endif /* HAVE_PUTENV_THAT_COPIES */
|
||||
}
|
||||
#else /* !USE_PUTENV_FOR_UNSET */
|
||||
for (envPtr = environ+index+1; ; envPtr++) {
|
||||
for (envPtr = (char **)(tenviron+index+1); ; envPtr++) {
|
||||
envPtr[-1] = *envPtr;
|
||||
if (*envPtr == NULL) {
|
||||
break;
|
||||
@@ -539,7 +571,7 @@ TclGetEnv(
|
||||
if (index != -1) {
|
||||
Tcl_DString envStr;
|
||||
|
||||
result = Tcl_ExternalToUtfDString(NULL, environ[index], -1, &envStr);
|
||||
result = tenviron2utfdstr(tenviron[index], -1, &envStr);
|
||||
result += length;
|
||||
if (*result == '=') {
|
||||
result++;
|
||||
@@ -701,7 +733,7 @@ ReplaceString(
|
||||
|
||||
const int growth = 5;
|
||||
|
||||
env.cache = ckrealloc(env.cache,
|
||||
env.cache = (char **)ckrealloc(env.cache,
|
||||
(env.cacheSize + growth) * sizeof(char *));
|
||||
env.cache[env.cacheSize] = newStr;
|
||||
(void) memset(env.cache+env.cacheSize+1, 0,
|
||||
|
||||
Reference in New Issue
Block a user