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