*** win/tclWinPort.h.original	Fri Dec 17 10:25:51 2004
--- win/tclWinPort.h	Fri Dec 17 10:42:34 2004
***************
*** 433,444 ****
  #define TCL_SHLIB_EXT ".dll"
  
  /*
!  * The following define ensures that we use the native putenv
   * implementation to modify the environment array.  This keeps
   * the C level environment in synch with the system level environment.
   */
  
! #define USE_PUTENV	1
  
  /*
   * Msvcrt's putenv() copies the string rather than takes ownership of it.
--- 433,445 ----
  #define TCL_SHLIB_EXT ".dll"
  
  /*
!  * The following defines ensure that we use the native putenv
   * implementation to modify the environment array.  This keeps
   * the C level environment in synch with the system level environment.
   */
  
! #define USE_PUTENV_FOR_SET	1
! #define USE_PUTENV_FOR_UNSET	1
  
  /*
   * Msvcrt's putenv() copies the string rather than takes ownership of it.
*** unix/tclUnixPort.h.original	Fri Nov 12 16:52:02 2004
--- unix/tclUnixPort.h	Fri Dec 17 10:56:23 2004
***************
*** 523,528 ****
--- 523,542 ----
  #endif
  
  /*
+  * The following define ensures that we use the native putenv
+  * implementation to add and modify the environment array.
+  * This avoids memory management problems when Tcl environment
+  * modifications are interleaved with putenv() calls by non-Tcl
+  * components of an application.
+  *
+  * We continue to use direct environ modification on unset because
+  * the UNIX version of putenv() does not support removal of environment
+  * variables.
+  */
+ 
+ #define USE_PUTENV_FOR_SET      1
+ 
+ /*
   * The following macros have trivial definitions, allowing generic code to 
   * address platform-specific issues.
   */
*** generic/tclEnv.c.original	Fri Dec 17 09:54:30 2004
--- generic/tclEnv.c	Fri Dec 17 10:50:21 2004
***************
*** 24,30 ****
  				/* Array containing all of the environment
  				 * strings that Tcl has allocated. */
  
! #ifndef USE_PUTENV
  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
--- 24,30 ----
  				/* Array containing all of the environment
  				 * strings that Tcl has allocated. */
  
! #ifndef USE_PUTENV_FOR_SET
  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
***************
*** 189,195 ****
      index = TclpFindVariable(name, &length);
  
      if (index == -1) {
! #ifndef USE_PUTENV
  	if ((length + 2) > environSize) {
  	    char **newEnviron;
  
--- 189,195 ----
      index = TclpFindVariable(name, &length);
  
      if (index == -1) {
! #ifndef USE_PUTENV_FOR_SET
  	if ((length + 2) > environSize) {
  	    char **newEnviron;
  
***************
*** 258,264 ****
      strcpy(p, p2);
      Tcl_DStringFree(&envString);
  
! #ifdef USE_PUTENV
      /*
       * Update the system environment.
       */
--- 258,264 ----
      strcpy(p, p2);
      Tcl_DStringFree(&envString);
  
! #ifdef USE_PUTENV_FOR_SET
      /*
       * Update the system environment.
       */
***************
*** 377,383 ****
      char *oldValue;
      int length;
      int index;
! #ifdef USE_PUTENV
      Tcl_DString envString;
      char *string;
  #else
--- 377,383 ----
      char *oldValue;
      int length;
      int index;
! #ifdef USE_PUTENV_FOR_UNSET
      Tcl_DString envString;
      char *string;
  #else
***************
*** 407,413 ****
       * update the interpreters or we will recurse.
       */
  
! #ifdef USE_PUTENV
      string = ckalloc((unsigned int) length+2);
      memcpy((VOID *) string, (VOID *) name, (size_t) length);
      string[length] = '=';
--- 407,418 ----
       * update the interpreters or we will recurse.
       */
  
! #ifdef USE_PUTENV_FOR_UNSET
!     /*
!      * This only works if assigning an environment variable to the empty string
!      * unsets it. This is how the Windows putenv() works but it does not work on
!      * UNIX.
!      */
      string = ckalloc((unsigned int) length+2);
      memcpy((VOID *) string, (VOID *) name, (size_t) length);
      string[length] = '=';
***************
*** 696,702 ****
  	ckfree((char *) environCache);
  	environCache = NULL;
  	cacheSize    = 0;
! #ifndef USE_PUTENV
  	environSize  = 0;
  #endif
      }
--- 701,707 ----
  	ckfree((char *) environCache);
  	environCache = NULL;
  	cacheSize    = 0;
! #ifndef USE_PUTENV_FOR_SET
  	environSize  = 0;
  #endif
      }
