tclEnv.c

Go 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  doxygen 1.5.1