tclEnv.cGo to the documentation of this file.00001 /* 00002 * tclEnv.c -- 00003 * 00004 * Tcl support for environment variables, including a setenv function. 00005 * This file contains the generic portion of the environment module. It 00006 * is primarily responsible for keeping the "env" arrays in sync with the 00007 * system environment variables. 00008 * 00009 * Copyright (c) 1991-1994 The Regents of the University of California. 00010 * Copyright (c) 1994-1998 Sun Microsystems, Inc. 00011 * 00012 * See the file "license.terms" for information on usage and redistribution of 00013 * this file, and for a DISCLAIMER OF ALL WARRANTIES. 00014 * 00015 * RCS: @(#) $Id: tclEnv.c,v 1.37 2007/12/13 15:23:16 dgp Exp $ 00016 */ 00017 00018 #include "tclInt.h" 00019 00020 TCL_DECLARE_MUTEX(envMutex) /* To serialize access to environ. */ 00021 00022 static struct { 00023 int cacheSize; /* Number of env strings in cache. */ 00024 char **cache; /* Array containing all of the environment 00025 * strings that Tcl has allocated. */ 00026 #ifndef USE_PUTENV 00027 char **ourEnviron; /* Cache of the array that we allocate. We 00028 * need to track this in case another 00029 * subsystem swaps around the environ array 00030 * like we do. */ 00031 int ourEnvironSize; /* Non-zero means that the environ array was 00032 * malloced and has this many total entries 00033 * allocated to it (not all may be in use at 00034 * once). Zero means that the environment 00035 * array is in its original static state. */ 00036 #endif 00037 } env; 00038 00039 /* 00040 * Declarations for local functions defined in this file: 00041 */ 00042 00043 static char * EnvTraceProc(ClientData clientData, Tcl_Interp *interp, 00044 const char *name1, const char *name2, int flags); 00045 static void ReplaceString(const char *oldStr, char *newStr); 00046 MODULE_SCOPE void TclSetEnv(const char *name, const char *value); 00047 MODULE_SCOPE void TclUnsetEnv(const char *name); 00048 #if defined(__CYGWIN__) && defined(__WIN32__) 00049 static void TclCygwinPutenv(const char *string); 00050 #endif 00051 00052 /* 00053 *---------------------------------------------------------------------- 00054 * 00055 * TclSetupEnv -- 00056 * 00057 * This function is invoked for an interpreter to make environment 00058 * variables accessible from that interpreter via the "env" associative 00059 * array. 00060 * 00061 * Results: 00062 * None. 00063 * 00064 * Side effects: 00065 * The interpreter is added to a list of interpreters managed by us, so 00066 * that its view of envariables can be kept consistent with the view in 00067 * other interpreters. If this is the first call to TclSetupEnv, then 00068 * additional initialization happens, such as copying the environment to 00069 * dynamically-allocated space for ease of management. 00070 * 00071 *---------------------------------------------------------------------- 00072 */ 00073 00074 void 00075 TclSetupEnv( 00076 Tcl_Interp *interp) /* Interpreter whose "env" array is to be 00077 * managed. */ 00078 { 00079 Tcl_DString envString; 00080 char *p1, *p2; 00081 int i; 00082 00083 /* 00084 * Synchronize the values in the environ array with the contents of the 00085 * Tcl "env" variable. To do this: 00086 * 1) Remove the trace that fires when the "env" var is unset. 00087 * 2) Unset the "env" variable. 00088 * 3) If there are no environ variables, create an empty "env" array. 00089 * Otherwise populate the array with current values. 00090 * 4) Add a trace that synchronizes the "env" array. 00091 */ 00092 00093 Tcl_UntraceVar2(interp, "env", NULL, 00094 TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS | 00095 TCL_TRACE_READS | TCL_TRACE_ARRAY, EnvTraceProc, NULL); 00096 00097 Tcl_UnsetVar2(interp, "env", NULL, TCL_GLOBAL_ONLY); 00098 00099 if (environ[0] == NULL) { 00100 Tcl_Obj *varNamePtr; 00101 00102 TclNewLiteralStringObj(varNamePtr, "env"); 00103 Tcl_IncrRefCount(varNamePtr); 00104 TclArraySet(interp, varNamePtr, NULL); 00105 Tcl_DecrRefCount(varNamePtr); 00106 } else { 00107 Tcl_MutexLock(&envMutex); 00108 for (i = 0; environ[i] != NULL; i++) { 00109 p1 = Tcl_ExternalToUtfDString(NULL, environ[i], -1, &envString); 00110 p2 = strchr(p1, '='); 00111 if (p2 == NULL) { 00112 /* 00113 * This condition seem to happen occasionally under some 00114 * versions of Solaris; ignore the entry. 00115 */ 00116 00117 continue; 00118 } 00119 p2++; 00120 p2[-1] = '\0'; 00121 Tcl_SetVar2(interp, "env", p1, p2, TCL_GLOBAL_ONLY); 00122 Tcl_DStringFree(&envString); 00123 } 00124 Tcl_MutexUnlock(&envMutex); 00125 } 00126 00127 Tcl_TraceVar2(interp, "env", NULL, 00128 TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS | 00129 TCL_TRACE_READS | TCL_TRACE_ARRAY, EnvTraceProc, NULL); 00130 } 00131 00132 /* 00133 *---------------------------------------------------------------------- 00134 * 00135 * TclSetEnv -- 00136 * 00137 * Set an environment variable, replacing an existing value or creating a 00138 * new variable if there doesn't exist a variable by the given name. This 00139 * function is intended to be a stand-in for the UNIX "setenv" function 00140 * so that applications using that function will interface properly to 00141 * Tcl. To make it a stand-in, the Makefile must define "TclSetEnv" to 00142 * "setenv". 00143 * 00144 * Results: 00145 * None. 00146 * 00147 * Side effects: 00148 * The environ array gets updated. 00149 * 00150 *---------------------------------------------------------------------- 00151 */ 00152 00153 void 00154 TclSetEnv( 00155 const char *name, /* Name of variable whose value is to be set 00156 * (UTF-8). */ 00157 const char *value) /* New value for variable (UTF-8). */ 00158 { 00159 Tcl_DString envString; 00160 int index, length, nameLength; 00161 char *p, *oldValue; 00162 const char *p2; 00163 00164 /* 00165 * Figure out where the entry is going to go. If the name doesn't already 00166 * exist, enlarge the array if necessary to make room. If the name exists, 00167 * free its old entry. 00168 */ 00169 00170 Tcl_MutexLock(&envMutex); 00171 index = TclpFindVariable(name, &length); 00172 00173 if (index == -1) { 00174 #ifndef USE_PUTENV 00175 /* 00176 * We need to handle the case where the environment may be changed 00177 * outside our control. ourEnvironSize is only valid if the current 00178 * environment is the one we allocated. [Bug 979640] 00179 */ 00180 00181 if ((env.ourEnviron != environ) || (length+2 > env.ourEnvironSize)) { 00182 char **newEnviron = (char **) 00183 ckalloc(((unsigned) length + 5) * sizeof(char *)); 00184 00185 memcpy(newEnviron, environ, length * sizeof(char *)); 00186 if ((env.ourEnvironSize != 0) && (env.ourEnviron != NULL)) { 00187 ckfree((char *) env.ourEnviron); 00188 } 00189 environ = env.ourEnviron = newEnviron; 00190 env.ourEnvironSize = length + 5; 00191 } 00192 index = length; 00193 environ[index + 1] = NULL; 00194 #endif /* USE_PUTENV */ 00195 oldValue = NULL; 00196 nameLength = strlen(name); 00197 } else { 00198 const char *env; 00199 00200 /* 00201 * Compare the new value to the existing value. If they're the same 00202 * then quit immediately (e.g. don't rewrite the value or propagate it 00203 * to other interpreters). Otherwise, when there are N interpreters 00204 * there will be N! propagations of the same value among the 00205 * interpreters. 00206 */ 00207 00208 env = Tcl_ExternalToUtfDString(NULL, environ[index], -1, &envString); 00209 if (strcmp(value, env + (length + 1)) == 0) { 00210 Tcl_DStringFree(&envString); 00211 Tcl_MutexUnlock(&envMutex); 00212 return; 00213 } 00214 Tcl_DStringFree(&envString); 00215 00216 oldValue = environ[index]; 00217 nameLength = length; 00218 } 00219 00220 /* 00221 * Create a new entry. Build a complete UTF string that contains a 00222 * "name=value" pattern. Then convert the string to the native encoding, 00223 * and set the environ array value. 00224 */ 00225 00226 p = ckalloc((unsigned) nameLength + strlen(value) + 2); 00227 strcpy(p, name); 00228 p[nameLength] = '='; 00229 strcpy(p+nameLength+1, value); 00230 p2 = Tcl_UtfToExternalDString(NULL, p, -1, &envString); 00231 00232 /* 00233 * Copy the native string to heap memory. 00234 */ 00235 00236 p = ckrealloc(p, strlen(p2) + 1); 00237 strcpy(p, p2); 00238 Tcl_DStringFree(&envString); 00239 00240 #ifdef USE_PUTENV 00241 /* 00242 * Update the system environment. 00243 */ 00244 00245 putenv(p); 00246 index = TclpFindVariable(name, &length); 00247 #else 00248 environ[index] = p; 00249 #endif /* USE_PUTENV */ 00250 00251 /* 00252 * Watch out for versions of putenv that copy the string (e.g. VC++). In 00253 * this case we need to free the string immediately. Otherwise update the 00254 * string in the cache. 00255 */ 00256 00257 if ((index != -1) && (environ[index] == p)) { 00258 ReplaceString(oldValue, p); 00259 #ifdef HAVE_PUTENV_THAT_COPIES 00260 } else { 00261 /* 00262 * This putenv() copies instead of taking ownership. 00263 */ 00264 00265 ckfree(p); 00266 #endif /* HAVE_PUTENV_THAT_COPIES */ 00267 } 00268 00269 Tcl_MutexUnlock(&envMutex); 00270 00271 if (!strcmp(name, "HOME")) { 00272 /* 00273 * If the user's home directory has changed, we must invalidate the 00274 * filesystem cache, because '~' expansions will now be incorrect. 00275 */ 00276 00277 Tcl_FSMountsChanged(NULL); 00278 } 00279 } 00280 00281 /* 00282 *---------------------------------------------------------------------- 00283 * 00284 * Tcl_PutEnv -- 00285 * 00286 * Set an environment variable. Similar to setenv except that the 00287 * information is passed in a single string of the form NAME=value, 00288 * rather than as separate name strings. This function is intended to be 00289 * a stand-in for the UNIX "putenv" function so that applications using 00290 * that function will interface properly to Tcl. To make it a stand-in, 00291 * the Makefile will define "Tcl_PutEnv" to "putenv". 00292 * 00293 * Results: 00294 * None. 00295 * 00296 * Side effects: 00297 * The environ array gets updated, as do all of the interpreters that we 00298 * manage. 00299 * 00300 *---------------------------------------------------------------------- 00301 */ 00302 00303 int 00304 Tcl_PutEnv( 00305 const char *assignment) /* Info about environment variable in the form 00306 * NAME=value. (native) */ 00307 { 00308 Tcl_DString nameString; 00309 const char *name; 00310 char *value; 00311 00312 if (assignment == NULL) { 00313 return 0; 00314 } 00315 00316 /* 00317 * First convert the native string to UTF. Then separate the string into 00318 * name and value parts, and call TclSetEnv to do all of the real work. 00319 */ 00320 00321 name = Tcl_ExternalToUtfDString(NULL, assignment, -1, &nameString); 00322 value = strchr(name, '='); 00323 00324 if ((value != NULL) && (value != name)) { 00325 value[0] = '\0'; 00326 TclSetEnv(name, value+1); 00327 } 00328 00329 Tcl_DStringFree(&nameString); 00330 return 0; 00331 } 00332 00333 /* 00334 *---------------------------------------------------------------------- 00335 * 00336 * TclUnsetEnv -- 00337 * 00338 * Remove an environment variable, updating the "env" arrays in all 00339 * interpreters managed by us. This function is intended to replace the 00340 * UNIX "unsetenv" function (but to do this the Makefile must be modified 00341 * to redefine "TclUnsetEnv" to "unsetenv". 00342 * 00343 * Results: 00344 * None. 00345 * 00346 * Side effects: 00347 * Interpreters are updated, as is environ. 00348 * 00349 *---------------------------------------------------------------------- 00350 */ 00351 00352 void 00353 TclUnsetEnv( 00354 const char *name) /* Name of variable to remove (UTF-8). */ 00355 { 00356 char *oldValue; 00357 int length; 00358 int index; 00359 #ifdef USE_PUTENV_FOR_UNSET 00360 Tcl_DString envString; 00361 char *string; 00362 #else 00363 char **envPtr; 00364 #endif /* USE_PUTENV_FOR_UNSET */ 00365 00366 Tcl_MutexLock(&envMutex); 00367 index = TclpFindVariable(name, &length); 00368 00369 /* 00370 * First make sure that the environment variable exists to avoid doing 00371 * needless work and to avoid recursion on the unset. 00372 */ 00373 00374 if (index == -1) { 00375 Tcl_MutexUnlock(&envMutex); 00376 return; 00377 } 00378 00379 /* 00380 * Remember the old value so we can free it if Tcl created the string. 00381 */ 00382 00383 oldValue = environ[index]; 00384 00385 /* 00386 * Update the system environment. This must be done before we update the 00387 * interpreters or we will recurse. 00388 */ 00389 00390 #ifdef USE_PUTENV_FOR_UNSET 00391 /* 00392 * For those platforms that support putenv to unset, Linux indicates 00393 * that no = should be included, and Windows requires it. 00394 */ 00395 00396 #ifdef WIN32 00397 string = ckalloc((unsigned) length+2); 00398 memcpy(string, name, (size_t) length); 00399 string[length] = '='; 00400 string[length+1] = '\0'; 00401 #else 00402 string = ckalloc((unsigned) length+1); 00403 memcpy(string, name, (size_t) length); 00404 string[length] = '\0'; 00405 #endif /* WIN32 */ 00406 00407 Tcl_UtfToExternalDString(NULL, string, -1, &envString); 00408 string = ckrealloc(string, (unsigned) Tcl_DStringLength(&envString)+1); 00409 strcpy(string, Tcl_DStringValue(&envString)); 00410 Tcl_DStringFree(&envString); 00411 00412 putenv(string); 00413 00414 /* 00415 * Watch out for versions of putenv that copy the string (e.g. VC++). In 00416 * this case we need to free the string immediately. Otherwise update the 00417 * string in the cache. 00418 */ 00419 00420 if (environ[index] == string) { 00421 ReplaceString(oldValue, string); 00422 #ifdef HAVE_PUTENV_THAT_COPIES 00423 } else { 00424 /* 00425 * This putenv() copies instead of taking ownership. 00426 */ 00427 00428 ckfree(string); 00429 #endif /* HAVE_PUTENV_THAT_COPIES */ 00430 } 00431 #else /* !USE_PUTENV_FOR_UNSET */ 00432 for (envPtr = environ+index+1; ; envPtr++) { 00433 envPtr[-1] = *envPtr; 00434 if (*envPtr == NULL) { 00435 break; 00436 } 00437 } 00438 ReplaceString(oldValue, NULL); 00439 #endif /* USE_PUTENV_FOR_UNSET */ 00440 00441 Tcl_MutexUnlock(&envMutex); 00442 } 00443 00444 /* 00445 *--------------------------------------------------------------------------- 00446 * 00447 * TclGetEnv -- 00448 * 00449 * Retrieve the value of an environment variable. 00450 * 00451 * Results: 00452 * The result is a pointer to a string specifying the value of the 00453 * environment variable, or NULL if that environment variable does not 00454 * exist. Storage for the result string is allocated in valuePtr; the 00455 * caller must call Tcl_DStringFree() when the result is no longer 00456 * needed. 00457 * 00458 * Side effects: 00459 * None. 00460 * 00461 *---------------------------------------------------------------------- 00462 */ 00463 00464 const char * 00465 TclGetEnv( 00466 const char *name, /* Name of environment variable to find 00467 * (UTF-8). */ 00468 Tcl_DString *valuePtr) /* Uninitialized or free DString in which the 00469 * value of the environment variable is 00470 * stored. */ 00471 { 00472 int length, index; 00473 const char *result; 00474 00475 Tcl_MutexLock(&envMutex); 00476 index = TclpFindVariable(name, &length); 00477 result = NULL; 00478 if (index != -1) { 00479 Tcl_DString envStr; 00480 00481 result = Tcl_ExternalToUtfDString(NULL, environ[index], -1, &envStr); 00482 result += length; 00483 if (*result == '=') { 00484 result++; 00485 Tcl_DStringInit(valuePtr); 00486 Tcl_DStringAppend(valuePtr, result, -1); 00487 result = Tcl_DStringValue(valuePtr); 00488 } else { 00489 result = NULL; 00490 } 00491 Tcl_DStringFree(&envStr); 00492 } 00493 Tcl_MutexUnlock(&envMutex); 00494 return result; 00495 } 00496 00497 /* 00498 *---------------------------------------------------------------------- 00499 * 00500 * EnvTraceProc -- 00501 * 00502 * This function is invoked whenever an environment variable is read, 00503 * modified or deleted. It propagates the change to the global "environ" 00504 * array. 00505 * 00506 * Results: 00507 * Always returns NULL to indicate success. 00508 * 00509 * Side effects: 00510 * Environment variable changes get propagated. If the whole "env" array 00511 * is deleted, then we stop managing things for this interpreter (usually 00512 * this happens because the whole interpreter is being deleted). 00513 * 00514 *---------------------------------------------------------------------- 00515 */ 00516 00517 /* ARGSUSED */ 00518 static char * 00519 EnvTraceProc( 00520 ClientData clientData, /* Not used. */ 00521 Tcl_Interp *interp, /* Interpreter whose "env" variable is being 00522 * modified. */ 00523 const char *name1, /* Better be "env". */ 00524 const char *name2, /* Name of variable being modified, or NULL if 00525 * whole array is being deleted (UTF-8). */ 00526 int flags) /* Indicates what's happening. */ 00527 { 00528 /* 00529 * For array traces, let TclSetupEnv do all the work. 00530 */ 00531 00532 if (flags & TCL_TRACE_ARRAY) { 00533 TclSetupEnv(interp); 00534 return NULL; 00535 } 00536 00537 /* 00538 * If name2 is NULL, then return and do nothing. 00539 */ 00540 00541 if (name2 == NULL) { 00542 return NULL; 00543 } 00544 00545 /* 00546 * If a value is being set, call TclSetEnv to do all of the work. 00547 */ 00548 00549 if (flags & TCL_TRACE_WRITES) { 00550 const char *value; 00551 00552 value = Tcl_GetVar2(interp, "env", name2, TCL_GLOBAL_ONLY); 00553 TclSetEnv(name2, value); 00554 } 00555 00556 /* 00557 * If a value is being read, call TclGetEnv to do all of the work. 00558 */ 00559 00560 if (flags & TCL_TRACE_READS) { 00561 Tcl_DString valueString; 00562 const char *value = TclGetEnv(name2, &valueString); 00563 00564 if (value == NULL) { 00565 return "no such variable"; 00566 } 00567 Tcl_SetVar2(interp, name1, name2, value, 0); 00568 Tcl_DStringFree(&valueString); 00569 } 00570 00571 /* 00572 * For unset traces, let TclUnsetEnv do all the work. 00573 */ 00574 00575 if (flags & TCL_TRACE_UNSETS) { 00576 TclUnsetEnv(name2); 00577 } 00578 return NULL; 00579 } 00580 00581 /* 00582 *---------------------------------------------------------------------- 00583 * 00584 * ReplaceString -- 00585 * 00586 * Replace one string with another in the environment variable cache. The 00587 * cache keeps track of all of the environment variables that Tcl has 00588 * modified so they can be freed later. 00589 * 00590 * Results: 00591 * None. 00592 * 00593 * Side effects: 00594 * May free the old string. 00595 * 00596 *---------------------------------------------------------------------- 00597 */ 00598 00599 static void 00600 ReplaceString( 00601 const char *oldStr, /* Old environment string. */ 00602 char *newStr) /* New environment string. */ 00603 { 00604 int i; 00605 00606 /* 00607 * Check to see if the old value was allocated by Tcl. If so, it needs to 00608 * be deallocated to avoid memory leaks. Note that this algorithm is O(n), 00609 * not O(1). This will result in n-squared behavior if lots of environment 00610 * changes are being made. 00611 */ 00612 00613 for (i = 0; i < env.cacheSize; i++) { 00614 if (env.cache[i]==oldStr || env.cache[i]==NULL) { 00615 break; 00616 } 00617 } 00618 if (i < env.cacheSize) { 00619 /* 00620 * Replace or delete the old value. 00621 */ 00622 00623 if (env.cache[i]) { 00624 ckfree(env.cache[i]); 00625 } 00626 00627 if (newStr) { 00628 env.cache[i] = newStr; 00629 } else { 00630 for (; i < env.cacheSize-1; i++) { 00631 env.cache[i] = env.cache[i+1]; 00632 } 00633 env.cache[env.cacheSize-1] = NULL; 00634 } 00635 } else { 00636 /* 00637 * We need to grow the cache in order to hold the new string. 00638 */ 00639 00640 const int growth = 5; 00641 00642 env.cache = (char **) ckrealloc((char *) env.cache, 00643 (env.cacheSize + growth) * sizeof(char *)); 00644 env.cache[env.cacheSize] = newStr; 00645 (void) memset(env.cache+env.cacheSize+1, (int) 0, 00646 (size_t) (growth-1) * sizeof(char*)); 00647 env.cacheSize += growth; 00648 } 00649 } 00650 00651 /* 00652 *---------------------------------------------------------------------- 00653 * 00654 * TclFinalizeEnvironment -- 00655 * 00656 * This function releases any storage allocated by this module that isn't 00657 * still in use by the global environment. Any strings that are still in 00658 * the environment will be leaked. 00659 * 00660 * Results: 00661 * None. 00662 * 00663 * Side effects: 00664 * May deallocate storage. 00665 * 00666 *---------------------------------------------------------------------- 00667 */ 00668 00669 void 00670 TclFinalizeEnvironment(void) 00671 { 00672 /* 00673 * For now we just deallocate the cache array and none of the environment 00674 * strings. This may leak more memory that strictly necessary, since some 00675 * of the strings may no longer be in the environment. However, 00676 * determining which ones are ok to delete is n-squared, and is pretty 00677 * unlikely, so we don't bother. 00678 */ 00679 00680 if (env.cache) { 00681 ckfree((char *) env.cache); 00682 env.cache = NULL; 00683 env.cacheSize = 0; 00684 #ifndef USE_PUTENV 00685 env.ourEnvironSize = 0; 00686 #endif 00687 } 00688 } 00689 00690 #if defined(__CYGWIN__) && defined(__WIN32__) 00691 00692 #include <windows.h> 00693 00694 /* 00695 * When using cygwin, when an environment variable changes, we need to synch 00696 * with both the cygwin environment (in case the application C code calls 00697 * fork) and the Windows environment (in case the application TCL code calls 00698 * exec, which calls the Windows CreateProcess function). 00699 */ 00700 00701 static void 00702 TclCygwinPutenv( 00703 const char *str) 00704 { 00705 char *name, *value; 00706 00707 /* 00708 * Get the name and value, so that we can change the environment variable 00709 * for Windows. 00710 */ 00711 00712 name = alloca(strlen(str) + 1); 00713 strcpy(name, str); 00714 for (value=name ; *value!='=' && *value!='\0' ; ++value) { 00715 /* Empty body */ 00716 } 00717 if (*value == '\0') { 00718 /* Can't happen. */ 00719 return; 00720 } 00721 *value = '\0'; 00722 ++value; 00723 if (*value == '\0') { 00724 value = NULL; 00725 } 00726 00727 /* 00728 * Set the cygwin environment variable. 00729 */ 00730 00731 #undef putenv 00732 if (value == NULL) { 00733 unsetenv(name); 00734 } else { 00735 putenv(str); 00736 } 00737 00738 /* 00739 * Before changing the environment variable in Windows, if this is PATH, 00740 * we need to convert the value back to a Windows style path. 00741 * 00742 * FIXME: The calling program may know it is running under windows, and 00743 * may have set the path to a Windows path, or, worse, appended or 00744 * prepended a Windows path to PATH. 00745 */ 00746 00747 if (strcmp(name, "PATH") != 0) { 00748 /* 00749 * If this is Path, eliminate any PATH variable, to prevent any 00750 * confusion. 00751 */ 00752 00753 if (strcmp(name, "Path") == 0) { 00754 SetEnvironmentVariable("PATH", NULL); 00755 unsetenv("PATH"); 00756 } 00757 00758 SetEnvironmentVariable(name, value); 00759 } else { 00760 char *buf; 00761 00762 /* 00763 * Eliminate any Path variable, to prevent any confusion. 00764 */ 00765 00766 SetEnvironmentVariable("Path", NULL); 00767 unsetenv("Path"); 00768 00769 if (value == NULL) { 00770 buf = NULL; 00771 } else { 00772 int size; 00773 00774 size = cygwin_posix_to_win32_path_list_buf_size(value); 00775 buf = alloca(size + 1); 00776 cygwin_posix_to_win32_path_list(value, buf); 00777 } 00778 00779 SetEnvironmentVariable(name, buf); 00780 } 00781 } 00782 #endif /* __CYGWIN__ && __WIN32__ */ 00783 00784 /* 00785 * Local Variables: 00786 * mode: c 00787 * c-basic-offset: 4 00788 * fill-column: 78 00789 * End: 00790 */
Generated on Wed Mar 12 12:18:15 2008 by 1.5.1 |