diff options
Diffstat (limited to 'generic/tclEnv.c')
| -rw-r--r-- | generic/tclEnv.c | 546 |
1 files changed, 230 insertions, 316 deletions
diff --git a/generic/tclEnv.c b/generic/tclEnv.c index f2395e6..7108436 100644 --- a/generic/tclEnv.c +++ b/generic/tclEnv.c @@ -1,79 +1,80 @@ /* * tclEnv.c -- * - * Tcl support for environment variables, including a setenv function. - * This file contains the generic portion of the environment module. It - * is primarily responsible for keeping the "env" arrays in sync with the - * system environment variables. + * Tcl support for environment variables, including a setenv + * procedure. This file contains the generic portion of the + * environment module. It is primarily responsible for keeping + * the "env" arrays in sync with the system environment variables. * * Copyright (c) 1991-1994 The Regents of the University of California. * Copyright (c) 1994-1998 Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tclInt.h" +#include "tclPort.h" -TCL_DECLARE_MUTEX(envMutex) /* To serialize access to environ. */ +TCL_DECLARE_MUTEX(envMutex) /* To serialize access to environ */ -static struct { - int cacheSize; /* Number of env strings in cache. */ - char **cache; /* Array containing all of the environment +static int cacheSize = 0; /* Number of env strings in environCache. */ +static char **environCache = NULL; + /* Array containing all of the environment * strings that Tcl has allocated. */ + #ifndef USE_PUTENV - char **ourEnviron; /* Cache of the array that we allocate. We - * need to track this in case another +static char **ourEnviron = NULL;/* Cache of the array that we allocate. + * We need to track this in case another * subsystem swaps around the environ array - * like we do. */ - int ourEnvironSize; /* Non-zero means that the environ array was + * like we do. + */ +static int environSize = 0; /* Non-zero means that the environ array was * malloced and has this many total entries * allocated to it (not all may be in use at - * once). Zero means that the environment + * once). Zero means that the environment * array is in its original static state. */ #endif -} env; /* - * Declarations for local functions defined in this file: + * Declarations for local procedures defined in this file: */ -static char * EnvTraceProc(ClientData clientData, Tcl_Interp *interp, - const char *name1, const char *name2, int flags); -static void ReplaceString(const char *oldStr, char *newStr); -MODULE_SCOPE void TclSetEnv(const char *name, const char *value); -MODULE_SCOPE void TclUnsetEnv(const char *name); - -#if defined(__CYGWIN__) - static void TclCygwinPutenv(char *string); -# define putenv TclCygwinPutenv -#endif +static char * EnvTraceProc _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, CONST char *name1, + CONST char *name2, int flags)); +static void ReplaceString _ANSI_ARGS_((CONST char *oldStr, + char *newStr)); +void TclSetEnv _ANSI_ARGS_((CONST char *name, + CONST char *value)); +void TclUnsetEnv _ANSI_ARGS_((CONST char *name)); /* *---------------------------------------------------------------------- * * TclSetupEnv -- * - * This function is invoked for an interpreter to make environment - * variables accessible from that interpreter via the "env" associative - * array. + * This procedure is invoked for an interpreter to make environment + * variables accessible from that interpreter via the "env" + * associative array. * * Results: * None. * * Side effects: - * The interpreter is added to a list of interpreters managed by us, so - * that its view of envariables can be kept consistent with the view in - * other interpreters. If this is the first call to TclSetupEnv, then - * additional initialization happens, such as copying the environment to - * dynamically-allocated space for ease of management. + * The interpreter is added to a list of interpreters managed + * by us, so that its view of envariables can be kept consistent + * with the view in other interpreters. If this is the first + * call to TclSetupEnv, then additional initialization happens, + * such as copying the environment to dynamically-allocated space + * for ease of management. * *---------------------------------------------------------------------- */ void -TclSetupEnv( - Tcl_Interp *interp) /* Interpreter whose "env" array is to be +TclSetupEnv(interp) + Tcl_Interp *interp; /* Interpreter whose "env" array is to be * managed. */ { Tcl_DString envString; @@ -81,27 +82,28 @@ TclSetupEnv( int i; /* - * Synchronize the values in the environ array with the contents of the - * Tcl "env" variable. To do this: + * Synchronize the values in the environ array with the contents + * of the Tcl "env" variable. To do this: * 1) Remove the trace that fires when the "env" var is unset. * 2) Unset the "env" variable. - * 3) If there are no environ variables, create an empty "env" array. - * Otherwise populate the array with current values. + * 3) If there are no environ variables, create an empty "env" + * array. Otherwise populate the array with current values. * 4) Add a trace that synchronizes the "env" array. */ - - Tcl_UntraceVar2(interp, "env", NULL, + + Tcl_UntraceVar2(interp, "env", (char *) NULL, TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS | - TCL_TRACE_READS | TCL_TRACE_ARRAY, EnvTraceProc, NULL); - - Tcl_UnsetVar2(interp, "env", NULL, TCL_GLOBAL_ONLY); - + TCL_TRACE_READS | TCL_TRACE_ARRAY, EnvTraceProc, + (ClientData) NULL); + + Tcl_UnsetVar2(interp, "env", (char *) NULL, TCL_GLOBAL_ONLY); + if (environ[0] == NULL) { Tcl_Obj *varNamePtr; - - TclNewLiteralStringObj(varNamePtr, "env"); + + varNamePtr = Tcl_NewStringObj("env", -1); Tcl_IncrRefCount(varNamePtr); - TclArraySet(interp, varNamePtr, NULL); + TclArraySet(interp, varNamePtr, NULL); Tcl_DecrRefCount(varNamePtr); } else { Tcl_MutexLock(&envMutex); @@ -111,23 +113,23 @@ TclSetupEnv( if (p2 == NULL) { /* * This condition seem to happen occasionally under some - * versions of Solaris, or when encoding accidents swallow the - * '='; ignore the entry. + * versions of Solaris; ignore the entry. */ - + continue; } p2++; p2[-1] = '\0'; - Tcl_SetVar2(interp, "env", p1, p2, TCL_GLOBAL_ONLY); + Tcl_SetVar2(interp, "env", p1, p2, TCL_GLOBAL_ONLY); Tcl_DStringFree(&envString); } Tcl_MutexUnlock(&envMutex); } - Tcl_TraceVar2(interp, "env", NULL, + Tcl_TraceVar2(interp, "env", (char *) NULL, TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS | - TCL_TRACE_READS | TCL_TRACE_ARRAY, EnvTraceProc, NULL); + TCL_TRACE_READS | TCL_TRACE_ARRAY, EnvTraceProc, + (ClientData) NULL); } /* @@ -135,12 +137,12 @@ TclSetupEnv( * * TclSetEnv -- * - * Set an environment variable, replacing an existing value or creating a - * new variable if there doesn't exist a variable by the given name. This - * function is intended to be a stand-in for the UNIX "setenv" function - * so that applications using that function will interface properly to - * Tcl. To make it a stand-in, the Makefile must define "TclSetEnv" to - * "setenv". + * Set an environment variable, replacing an existing value + * or creating a new variable if there doesn't exist a variable + * by the given name. This procedure is intended to be a + * stand-in for the UNIX "setenv" procedure so that applications + * using that procedure will interface properly to Tcl. To make + * it a stand-in, the Makefile must define "TclSetEnv" to "setenv". * * Results: * None. @@ -152,20 +154,20 @@ TclSetupEnv( */ void -TclSetEnv( - const char *name, /* Name of variable whose value is to be set - * (UTF-8). */ - const char *value) /* New value for variable (UTF-8). */ +TclSetEnv(name, value) + CONST char *name; /* Name of variable whose value is to be + * set (UTF-8). */ + CONST char *value; /* New value for variable (UTF-8). */ { Tcl_DString envString; int index, length, nameLength; char *p, *oldValue; - const char *p2; + CONST char *p2; /* - * Figure out where the entry is going to go. If the name doesn't already - * exist, enlarge the array if necessary to make room. If the name exists, - * free its old entry. + * Figure out where the entry is going to go. If the name doesn't + * already exist, enlarge the array if necessary to make room. If the + * name exists, free its old entry. */ Tcl_MutexLock(&envMutex); @@ -175,39 +177,40 @@ TclSetEnv( #ifndef USE_PUTENV /* * We need to handle the case where the environment may be changed - * outside our control. ourEnvironSize is only valid if the current + * outside our control. environSize is only valid if the current * environment is the one we allocated. [Bug 979640] */ - - if ((env.ourEnviron != environ) || (length+2 > env.ourEnvironSize)) { - char **newEnviron = (char **) - ckalloc(((unsigned) length + 5) * sizeof(char *)); - - memcpy(newEnviron, environ, length * sizeof(char *)); - if ((env.ourEnvironSize != 0) && (env.ourEnviron != NULL)) { - ckfree((char *) env.ourEnviron); + if ((ourEnviron != environ) || ((length + 2) > environSize)) { + char **newEnviron; + + newEnviron = (char **) ckalloc((unsigned) + ((length + 5) * sizeof(char *))); + memcpy((VOID *) newEnviron, (VOID *) environ, + length*sizeof(char *)); + if ((environSize != 0) && (ourEnviron != NULL)) { + ckfree((char *) ourEnviron); } - environ = env.ourEnviron = newEnviron; - env.ourEnvironSize = length + 5; + environ = ourEnviron = newEnviron; + environSize = length + 5; } index = length; environ[index + 1] = NULL; -#endif /* USE_PUTENV */ +#endif oldValue = NULL; nameLength = strlen(name); } else { - const char *env; + CONST char *env; /* - * Compare the new value to the existing value. If they're the same - * then quit immediately (e.g. don't rewrite the value or propagate it - * to other interpreters). Otherwise, when there are N interpreters - * there will be N! propagations of the same value among the - * interpreters. + * Compare the new value to the existing value. If they're + * the same then quit immediately (e.g. don't rewrite the + * value or propagate it to other interpreters). Otherwise, + * when there are N interpreters there will be N! propagations + * of the same value among the interpreters. */ env = Tcl_ExternalToUtfDString(NULL, environ[index], -1, &envString); - if (strcmp(value, env + (length + 1)) == 0) { + if (strcmp(value, (env + length + 1)) == 0) { Tcl_DStringFree(&envString); Tcl_MutexUnlock(&envMutex); return; @@ -219,12 +222,12 @@ TclSetEnv( } /* - * Create a new entry. Build a complete UTF string that contains a - * "name=value" pattern. Then convert the string to the native encoding, - * and set the environ array value. + * Create a new entry. Build a complete UTF string that contains + * a "name=value" pattern. Then convert the string to the native + * encoding, and set the environ array value. */ - p = ckalloc((unsigned) nameLength + strlen(value) + 2); + p = (char *) ckalloc((unsigned) (nameLength + strlen(value) + 2)); strcpy(p, name); p[nameLength] = '='; strcpy(p+nameLength+1, value); @@ -233,8 +236,8 @@ TclSetEnv( /* * Copy the native string to heap memory. */ - - p = ckrealloc(p, strlen(p2) + 1); + + p = (char *) ckrealloc(p, (unsigned) (strlen(p2) + 1)); strcpy(p, p2); Tcl_DStringFree(&envString); @@ -247,35 +250,32 @@ TclSetEnv( index = TclpFindVariable(name, &length); #else environ[index] = p; -#endif /* USE_PUTENV */ +#endif /* - * Watch out for versions of putenv that copy the string (e.g. VC++). In - * this case we need to free the string immediately. Otherwise update the - * string in the cache. + * Watch out for versions of putenv that copy the string (e.g. VC++). + * In this case we need to free the string immediately. Otherwise + * update the string in the cache. */ if ((index != -1) && (environ[index] == p)) { ReplaceString(oldValue, p); #ifdef HAVE_PUTENV_THAT_COPIES } else { - /* - * This putenv() copies instead of taking ownership. - */ - + /* This putenv() copies instead of taking ownership */ ckfree(p); -#endif /* HAVE_PUTENV_THAT_COPIES */ +#endif } Tcl_MutexUnlock(&envMutex); - + if (!strcmp(name, "HOME")) { - /* - * If the user's home directory has changed, we must invalidate the - * filesystem cache, because '~' expansions will now be incorrect. + /* + * If the user's home directory has changed, we must invalidate + * the filesystem cache, because '~' expansions will now be + * incorrect. */ - - Tcl_FSMountsChanged(NULL); + Tcl_FSMountsChanged(NULL); } } @@ -284,42 +284,44 @@ TclSetEnv( * * Tcl_PutEnv -- * - * Set an environment variable. Similar to setenv except that the - * information is passed in a single string of the form NAME=value, - * rather than as separate name strings. This function is intended to be - * a stand-in for the UNIX "putenv" function so that applications using - * that function will interface properly to Tcl. To make it a stand-in, - * the Makefile will define "Tcl_PutEnv" to "putenv". + * Set an environment variable. Similar to setenv except that + * the information is passed in a single string of the form + * NAME=value, rather than as separate name strings. This procedure + * is intended to be a stand-in for the UNIX "putenv" procedure + * so that applications using that procedure will interface + * properly to Tcl. To make it a stand-in, the Makefile will + * define "Tcl_PutEnv" to "putenv". * * Results: * None. * * Side effects: - * The environ array gets updated, as do all of the interpreters that we - * manage. + * The environ array gets updated, as do all of the interpreters + * that we manage. * *---------------------------------------------------------------------- */ int -Tcl_PutEnv( - const char *assignment) /* Info about environment variable in the form - * NAME=value. (native) */ +Tcl_PutEnv(string) + CONST char *string; /* Info about environment variable in the + * form NAME=value. (native) */ { - Tcl_DString nameString; - const char *name; + Tcl_DString nameString; + CONST char *name; char *value; - if (assignment == NULL) { + if (string == NULL) { return 0; } /* - * First convert the native string to UTF. Then separate the string into - * name and value parts, and call TclSetEnv to do all of the real work. + * First convert the native string to UTF. Then separate the + * string into name and value parts, and call TclSetEnv to do + * all of the real work. */ - name = Tcl_ExternalToUtfDString(NULL, assignment, -1, &nameString); + name = Tcl_ExternalToUtfDString(NULL, string, -1, &nameString); value = strchr(name, '='); if ((value != NULL) && (value != name)) { @@ -336,10 +338,11 @@ Tcl_PutEnv( * * TclUnsetEnv -- * - * Remove an environment variable, updating the "env" arrays in all - * interpreters managed by us. This function is intended to replace the - * UNIX "unsetenv" function (but to do this the Makefile must be modified - * to redefine "TclUnsetEnv" to "unsetenv". + * Remove an environment variable, updating the "env" arrays + * in all interpreters managed by us. This function is intended + * to replace the UNIX "unsetenv" function (but to do this the + * Makefile must be modified to redefine "TclUnsetEnv" to + * "unsetenv". * * Results: * None. @@ -351,8 +354,8 @@ Tcl_PutEnv( */ void -TclUnsetEnv( - const char *name) /* Name of variable to remove (UTF-8). */ +TclUnsetEnv(name) + CONST char *name; /* Name of variable to remove (UTF-8). */ { char *oldValue; int length; @@ -362,21 +365,20 @@ TclUnsetEnv( char *string; #else char **envPtr; -#endif /* USE_PUTENV_FOR_UNSET */ +#endif Tcl_MutexLock(&envMutex); index = TclpFindVariable(name, &length); /* - * First make sure that the environment variable exists to avoid doing - * needless work and to avoid recursion on the unset. + * First make sure that the environment variable exists to avoid + * doing needless work and to avoid recursion on the unset. */ if (index == -1) { Tcl_MutexUnlock(&envMutex); return; } - /* * Remember the old value so we can free it if Tcl created the string. */ @@ -384,8 +386,8 @@ TclUnsetEnv( oldValue = environ[index]; /* - * Update the system environment. This must be done before we update the - * interpreters or we will recurse. + * Update the system environment. This must be done before we + * update the interpreters or we will recurse. */ #ifdef USE_PUTENV_FOR_UNSET @@ -393,43 +395,39 @@ TclUnsetEnv( * For those platforms that support putenv to unset, Linux indicates * that no = should be included, and Windows requires it. */ - -#if defined(__WIN32__) || defined(__CYGWIN__) - string = ckalloc((unsigned) length+2); - memcpy(string, name, (size_t) length); +#ifdef WIN32 + string = ckalloc((unsigned int) length+2); + memcpy((VOID *) string, (VOID *) name, (size_t) length); string[length] = '='; string[length+1] = '\0'; #else - string = ckalloc((unsigned) length+1); - memcpy(string, name, (size_t) length); + string = ckalloc((unsigned int) length+1); + memcpy((VOID *) string, (VOID *) name, (size_t) length); string[length] = '\0'; -#endif /* WIN32 */ +#endif Tcl_UtfToExternalDString(NULL, string, -1, &envString); - string = ckrealloc(string, (unsigned) Tcl_DStringLength(&envString)+1); + string = ckrealloc(string, (unsigned) (Tcl_DStringLength(&envString)+1)); strcpy(string, Tcl_DStringValue(&envString)); Tcl_DStringFree(&envString); putenv(string); /* - * Watch out for versions of putenv that copy the string (e.g. VC++). In - * this case we need to free the string immediately. Otherwise update the - * string in the cache. + * Watch out for versions of putenv that copy the string (e.g. VC++). + * In this case we need to free the string immediately. Otherwise + * update the string in the cache. */ if (environ[index] == string) { ReplaceString(oldValue, string); #ifdef HAVE_PUTENV_THAT_COPIES } else { - /* - * This putenv() copies instead of taking ownership. - */ - + /* This putenv() copies instead of taking ownership */ ckfree(string); -#endif /* HAVE_PUTENV_THAT_COPIES */ +#endif } -#else /* !USE_PUTENV_FOR_UNSET */ +#else for (envPtr = environ+index+1; ; envPtr++) { envPtr[-1] = *envPtr; if (*envPtr == NULL) { @@ -437,7 +435,7 @@ TclUnsetEnv( } } ReplaceString(oldValue, NULL); -#endif /* USE_PUTENV_FOR_UNSET */ +#endif Tcl_MutexUnlock(&envMutex); } @@ -451,10 +449,10 @@ TclUnsetEnv( * * Results: * The result is a pointer to a string specifying the value of the - * environment variable, or NULL if that environment variable does not - * exist. Storage for the result string is allocated in valuePtr; the - * caller must call Tcl_DStringFree() when the result is no longer - * needed. + * environment variable, or NULL if that environment variable does + * not exist. Storage for the result string is allocated in valuePtr; + * the caller must call Tcl_DStringFree() when the result is no + * longer needed. * * Side effects: * None. @@ -462,23 +460,23 @@ TclUnsetEnv( *---------------------------------------------------------------------- */ -const char * -TclGetEnv( - const char *name, /* Name of environment variable to find +CONST char * +TclGetEnv(name, valuePtr) + CONST char *name; /* Name of environment variable to find * (UTF-8). */ - Tcl_DString *valuePtr) /* Uninitialized or free DString in which the - * value of the environment variable is + Tcl_DString *valuePtr; /* Uninitialized or free DString in which + * the value of the environment variable is * stored. */ { int length, index; - const char *result; + CONST char *result; Tcl_MutexLock(&envMutex); index = TclpFindVariable(name, &length); result = NULL; if (index != -1) { Tcl_DString envStr; - + result = Tcl_ExternalToUtfDString(NULL, environ[index], -1, &envStr); result += length; if (*result == '=') { @@ -500,31 +498,32 @@ TclGetEnv( * * EnvTraceProc -- * - * This function is invoked whenever an environment variable is read, - * modified or deleted. It propagates the change to the global "environ" - * array. + * This procedure is invoked whenever an environment variable + * is read, modified or deleted. It propagates the change to the global + * "environ" array. * * Results: * Always returns NULL to indicate success. * * Side effects: - * Environment variable changes get propagated. If the whole "env" array - * is deleted, then we stop managing things for this interpreter (usually - * this happens because the whole interpreter is being deleted). + * Environment variable changes get propagated. If the whole + * "env" array is deleted, then we stop managing things for + * this interpreter (usually this happens because the whole + * interpreter is being deleted). * *---------------------------------------------------------------------- */ /* ARGSUSED */ static char * -EnvTraceProc( - ClientData clientData, /* Not used. */ - Tcl_Interp *interp, /* Interpreter whose "env" variable is being - * modified. */ - const char *name1, /* Better be "env". */ - const char *name2, /* Name of variable being modified, or NULL if - * whole array is being deleted (UTF-8). */ - int flags) /* Indicates what's happening. */ +EnvTraceProc(clientData, interp, name1, name2, flags) + ClientData clientData; /* Not used. */ + Tcl_Interp *interp; /* Interpreter whose "env" variable is + * being modified. */ + CONST char *name1; /* Better be "env". */ + CONST char *name2; /* Name of variable being modified, or NULL + * if whole array is being deleted (UTF-8). */ + int flags; /* Indicates what's happening. */ { /* * For array traces, let TclSetupEnv do all the work. @@ -538,7 +537,7 @@ EnvTraceProc( /* * If name2 is NULL, then return and do nothing. */ - + if (name2 == NULL) { return NULL; } @@ -548,8 +547,8 @@ EnvTraceProc( */ if (flags & TCL_TRACE_WRITES) { - const char *value; - + CONST char *value; + value = Tcl_GetVar2(interp, "env", name2, TCL_GLOBAL_ONLY); TclSetEnv(name2, value); } @@ -560,8 +559,9 @@ EnvTraceProc( if (flags & TCL_TRACE_READS) { Tcl_DString valueString; - const char *value = TclGetEnv(name2, &valueString); + CONST char *value; + value = TclGetEnv(name2, &valueString); if (value == NULL) { return "no such variable"; } @@ -584,9 +584,9 @@ EnvTraceProc( * * ReplaceString -- * - * Replace one string with another in the environment variable cache. The - * cache keeps track of all of the environment variables that Tcl has - * modified so they can be freed later. + * Replace one string with another in the environment variable + * cache. The cache keeps track of all of the environment + * variables that Tcl has modified so they can be freed later. * * Results: * None. @@ -598,54 +598,61 @@ EnvTraceProc( */ static void -ReplaceString( - const char *oldStr, /* Old environment string. */ - char *newStr) /* New environment string. */ +ReplaceString(oldStr, newStr) + CONST char *oldStr; /* Old environment string. */ + char *newStr; /* New environment string. */ { int i; + char **newCache; /* - * Check to see if the old value was allocated by Tcl. If so, it needs to - * be deallocated to avoid memory leaks. Note that this algorithm is O(n), - * not O(1). This will result in n-squared behavior if lots of environment - * changes are being made. + * Check to see if the old value was allocated by Tcl. If so, + * it needs to be deallocated to avoid memory leaks. Note that this + * algorithm is O(n), not O(1). This will result in n-squared behavior + * if lots of environment changes are being made. */ - for (i = 0; i < env.cacheSize; i++) { - if (env.cache[i]==oldStr || env.cache[i]==NULL) { + for (i = 0; i < cacheSize; i++) { + if ((environCache[i] == oldStr) || (environCache[i] == NULL)) { break; } } - if (i < env.cacheSize) { + if (i < cacheSize) { /* * Replace or delete the old value. */ - if (env.cache[i]) { - ckfree(env.cache[i]); + if (environCache[i]) { + ckfree(environCache[i]); } if (newStr) { - env.cache[i] = newStr; + environCache[i] = newStr; } else { - for (; i < env.cacheSize-1; i++) { - env.cache[i] = env.cache[i+1]; + for (; i < cacheSize-1; i++) { + environCache[i] = environCache[i+1]; } - env.cache[env.cacheSize-1] = NULL; + environCache[cacheSize-1] = NULL; } } else { + int allocatedSize = (cacheSize + 5) * sizeof(char *); + /* * We need to grow the cache in order to hold the new string. */ - const int growth = 5; + newCache = (char **) ckalloc((unsigned) allocatedSize); + (VOID *) memset(newCache, (int) 0, (size_t) allocatedSize); - env.cache = (char **) ckrealloc((char *) env.cache, - (env.cacheSize + growth) * sizeof(char *)); - env.cache[env.cacheSize] = newStr; - (void) memset(env.cache+env.cacheSize+1, (int) 0, - (size_t) (growth-1) * sizeof(char*)); - env.cacheSize += growth; + if (environCache) { + memcpy((VOID *) newCache, (VOID *) environCache, + (size_t) (cacheSize * sizeof(char*))); + ckfree((char *) environCache); + } + environCache = newCache; + environCache[cacheSize] = newStr; + environCache[cacheSize+1] = NULL; + cacheSize += 5; } } @@ -654,9 +661,9 @@ ReplaceString( * * TclFinalizeEnvironment -- * - * This function releases any storage allocated by this module that isn't - * still in use by the global environment. Any strings that are still in - * the environment will be leaked. + * This function releases any storage allocated by this module + * that isn't still in use by the global environment. Any + * strings that are still in the environment will be leaked. * * Results: * None. @@ -668,119 +675,26 @@ ReplaceString( */ void -TclFinalizeEnvironment(void) +TclFinalizeEnvironment() { /* * For now we just deallocate the cache array and none of the environment - * strings. This may leak more memory that strictly necessary, since some - * of the strings may no longer be in the environment. However, + * strings. This may leak more memory that strictly necessary, since some + * of the strings may no longer be in the environment. However, * determining which ones are ok to delete is n-squared, and is pretty * unlikely, so we don't bother. */ - if (env.cache) { - ckfree((char *) env.cache); - env.cache = NULL; - env.cacheSize = 0; + if (environCache) { + ckfree((char *) environCache); + environCache = NULL; + cacheSize = 0; #ifndef USE_PUTENV - env.ourEnvironSize = 0; + environSize = 0; #endif } } -#if defined(__CYGWIN__) - -/* - * When using cygwin, when an environment variable changes, we need to synch - * with both the cygwin environment (in case the application C code calls - * fork) and the Windows environment (in case the application TCL code calls - * exec, which calls the Windows CreateProcess function). - */ -DLLIMPORT extern void __stdcall SetEnvironmentVariableA(const char*, const char *); - -static void -TclCygwinPutenv( - char *str) -{ - char *name, *value; - - /* - * Get the name and value, so that we can change the environment variable - * for Windows. - */ - - name = alloca(strlen(str) + 1); - strcpy(name, str); - for (value=name ; *value!='=' && *value!='\0' ; ++value) { - /* Empty body */ - } - if (*value == '\0') { - /* Can't happen. */ - return; - } - *value = '\0'; - ++value; - if (*value == '\0') { - value = NULL; - } - - /* - * Set the cygwin environment variable. - */ - -#undef putenv - if (value == NULL) { - unsetenv(name); - } else { - putenv(str); - } - - /* - * Before changing the environment variable in Windows, if this is PATH, - * we need to convert the value back to a Windows style path. - * - * FIXME: The calling program may know it is running under windows, and - * may have set the path to a Windows path, or, worse, appended or - * prepended a Windows path to PATH. - */ - - if (strcmp(name, "PATH") != 0) { - /* - * If this is Path, eliminate any PATH variable, to prevent any - * confusion. - */ - - if (strcmp(name, "Path") == 0) { - SetEnvironmentVariableA("PATH", NULL); - unsetenv("PATH"); - } - - SetEnvironmentVariableA(name, value); - } else { - char *buf; - - /* - * Eliminate any Path variable, to prevent any confusion. - */ - - SetEnvironmentVariableA("Path", NULL); - unsetenv("Path"); - - if (value == NULL) { - buf = NULL; - } else { - int size; - - size = cygwin_conv_path_list(0, value, NULL, 0); - buf = alloca(size + 1); - cygwin_conv_path_list(0, value, buf, size); - } - - SetEnvironmentVariableA(name, buf); - } -} -#endif /* __CYGWIN__ */ - /* * Local Variables: * mode: c |
