[41650] trunk/base/src/pextlib1.0/Pextlib.c

blb at macports.org blb at macports.org
Sat Nov 8 01:05:34 PST 2008


Revision: 41650
          http://trac.macports.org/changeset/41650
Author:   blb at macports.org
Date:     2008-11-08 01:05:33 -0800 (Sat, 08 Nov 2008)
Log Message:
-----------
pextlib1.0/Pextlib.c - move away from "environ = calloc(1, sizeof(char *));"
as that appears to tickle some memory bug on Mac OS X 10.4 tclsh which then
causes apparently-random crashes.  Instead, create a list of which variables
are set in the environment, storing in a Tcl list (since that's much easier
for a dynamic list like this), then loop through that list and unsetenv()
each one.  No crashing on 10.3-10.5 and tests/unsetenv.tcl pass (hopefully
final bit for #13930).

Modified Paths:
--------------
    trunk/base/src/pextlib1.0/Pextlib.c

Modified: trunk/base/src/pextlib1.0/Pextlib.c
===================================================================
--- trunk/base/src/pextlib1.0/Pextlib.c	2008-11-08 08:51:26 UTC (rev 41649)
+++ trunk/base/src/pextlib1.0/Pextlib.c	2008-11-08 09:05:33 UTC (rev 41650)
@@ -1129,6 +1129,13 @@
 int UnsetEnvCmd(ClientData clientData UNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
 {
     char *name;
+    char **envp;
+    char *equals;
+    size_t len;
+    Tcl_Obj *tclList;
+    int listLength;
+    Tcl_Obj **listArray;
+    int loopCounter;
     
     if (objc != 2) {
         Tcl_WrongNumArgs(interp, 1, objv, "name");
@@ -1143,10 +1150,24 @@
 
     if (strcmp(name, "*") == 0) {
         /* unset all current environment variables; it'd be best to use
-           clearenv() but that is not yet standardized, instead use this
-           technique which appears to be good across platforms, see eg:
-           <http://lists.freebsd.org/pipermail/freebsd-stable/2008-June/043136.html> */
-        environ = calloc(1, sizeof(char *));
+           clearenv() but that is not yet standardized, instead use Tcl's
+           list capability to easily build an array of strings for each
+           env name, then loop through that list to unsetenv() each one */
+        tclList = Tcl_NewListObj( 0, NULL );
+        Tcl_IncrRefCount( tclList );
+        /* unset all current environment variables */
+        for (envp = environ; *envp != NULL; envp++) {
+            equals = strchr(*envp, '=');
+            if (equals != NULL) {
+                len = equals - *envp;
+                Tcl_ListObjAppendElement(interp, tclList, Tcl_NewStringObj(*envp, len));
+            }
+        }
+        Tcl_ListObjGetElements(interp, tclList, &listLength, &listArray);
+        for (loopCounter = 0; loopCounter < listLength; loopCounter++) {
+            unsetenv(Tcl_GetString(listArray[loopCounter]));
+        }
+        Tcl_DecrRefCount( tclList );
     } else {
         (void) unsetenv(name);
     }
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macports-changes/attachments/20081108/b8d45c5c/attachment.html>


More information about the macports-changes mailing list