Tcl Source Code

Artifact [66a9e32f54]
Login

Artifact 66a9e32f5480d0aa97c58a6415277b98709d1fa3:

Attachment "channel-intrep.patch" to ticket [2407783fff] added by andreas_kupries 2008-12-10 06:27:30.
Index: ChangeLog
===================================================================
RCS file: /cvsroot/tcl/tcl/ChangeLog,v
retrieving revision 1.3975.2.133
diff -w -u -r1.3975.2.133 ChangeLog
--- ChangeLog	4 Dec 2008 17:45:02 -0000	1.3975.2.133
+++ ChangeLog	9 Dec 2008 23:26:49 -0000
@@ -1,3 +1,12 @@
+2008-12-09  Andreas Kupries   <[email protected]>
+
+	* generic/tclIO.c (SetChannelFromAny and related): Modified the
+	internal representation of the tclChannelType to contain not only
+	the ChannelState pointer, but also a reference to the interpreter
+	it was made in. Invalidate and recompute the internal
+	representation when it is used in a different interpreter
+	(Like cmdName intrep's). [Bug 2407783].
+
 2008-12-04  Don Porter  <[email protected]>
 
 	* generic/tclPathObj.c (Tcl_FSGetNormalizedPath):        Added another
Index: generic/tclIO.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclIO.c,v
retrieving revision 1.137.2.9
diff -w -u -r1.137.2.9 tclIO.c
--- generic/tclIO.c	2 Dec 2008 18:23:51 -0000	1.137.2.9
+++ generic/tclIO.c	9 Dec 2008 23:26:49 -0000
@@ -220,6 +220,10 @@
     ((ChannelState *) (objPtr)->internalRep.otherValuePtr)
 #define SET_CHANNELSTATE(objPtr, storePtr) \
     ((objPtr)->internalRep.otherValuePtr = (void *) (storePtr))
+#define GET_CHANNELINTERP(objPtr) \
+    ((Interp *) (objPtr)->internalRep.twoPtrValue.ptr2)
+#define SET_CHANNELINTERP(objPtr, storePtr) \
+    ((objPtr)->internalRep.twoPtrValue.ptr2 = (void *) (storePtr))
 
 #define BUSY_STATE(st,fl) \
      ((((st)->csPtrR) && ((fl) & TCL_READABLE)) || \
@@ -10613,8 +10617,11 @@
 				 * currently have an internal rep.*/
 {
     ChannelState *statePtr = GET_CHANNELSTATE(srcPtr);
+    Interp       *interpPtr = GET_CHANNELINTERP(srcPtr);
     SET_CHANNELSTATE(copyPtr, statePtr);
+    SET_CHANNELINTERP(copyPtr, interpPtr);
     Tcl_Preserve((ClientData) statePtr);
+    Tcl_Preserve((ClientData) interpPtr);
     copyPtr->typePtr = &tclChannelType;
 }
 
@@ -10641,6 +10648,7 @@
     register Tcl_Obj *objPtr)	/* The object to convert. */
 {
     ChannelState *statePtr;
+    Interp       *interpPtr;
 
     if (objPtr->typePtr == &tclChannelType) {
 	/*
@@ -10648,9 +10656,14 @@
 	 * Ensure consistency checks are done.
 	 */
 	statePtr = GET_CHANNELSTATE(objPtr);
+	interpPtr = GET_CHANNELINTERP(objPtr);
+	if ((interpPtr != (Interp*) interp) ||
+	    (statePtr->flags & (CHANNEL_TAINTED|CHANNEL_CLOSED))) {
 	if (statePtr->flags & (CHANNEL_TAINTED|CHANNEL_CLOSED)) {
 	    ResetFlag(statePtr, CHANNEL_TAINTED);
+	    }
 	    Tcl_Release((ClientData) statePtr);
+	    Tcl_Release((ClientData) interpPtr);
 	    UpdateStringOfChannel(objPtr);
 	    objPtr->typePtr = NULL;
 	}
@@ -10674,7 +10687,9 @@
 	TclFreeIntRep(objPtr);
 	statePtr = ((Channel *)chan)->state;
 	Tcl_Preserve((ClientData) statePtr);
+	Tcl_Preserve((ClientData) interp);
 	SET_CHANNELSTATE(objPtr, statePtr);
+	SET_CHANNELINTERP(objPtr, interp);
 	objPtr->typePtr = &tclChannelType;
     }
     return TCL_OK;
@@ -10738,6 +10753,7 @@
     Tcl_Obj *objPtr)		/* Object with internal rep to free. */
 {
     Tcl_Release((ClientData) GET_CHANNELSTATE(objPtr));
+    Tcl_Release((ClientData) GET_CHANNELINTERP(objPtr));
 }
 
 #if 0