summaryrefslogtreecommitdiffstats
path: root/generic/tclIO.c
diff options
context:
space:
mode:
authorandreas_kupries <akupries@shaw.ca>2008-12-11 17:30:18 (GMT)
committerandreas_kupries <akupries@shaw.ca>2008-12-11 17:30:18 (GMT)
commit6cb99f7bf8a960b9c8db1d06c4509fea270989b1 (patch)
tree84e713e17a14c7002afd51995234808c2c8b99db /generic/tclIO.c
parent1e9af660c1936aa10a345ac8f0ee41f74143c698 (diff)
downloadtcl-6cb99f7bf8a960b9c8db1d06c4509fea270989b1.zip
tcl-6cb99f7bf8a960b9c8db1d06c4509fea270989b1.tar.gz
tcl-6cb99f7bf8a960b9c8db1d06c4509fea270989b1.tar.bz2
* generic/tclIO.c (SetChannelFromAny and related): Modified the
* tests/io.test: 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). Added testcase. [Bug 2407783].
Diffstat (limited to 'generic/tclIO.c')
-rw-r--r--generic/tclIO.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 09ca6fa..12905de 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclIO.c,v 1.153 2008/12/09 20:16:29 dgp Exp $
+ * RCS: @(#) $Id: tclIO.c,v 1.154 2008/12/11 17:30:18 andreas_kupries Exp $
*/
#include "tclInt.h"
@@ -222,6 +222,10 @@ static const Tcl_ObjType tclChannelType = {
((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)) || \
@@ -10611,9 +10615,11 @@ DupChannelIntRep(
register Tcl_Obj *copyPtr) /* Object with internal rep to set. Must not
* currently have an internal rep.*/
{
- ChannelState *statePtr = GET_CHANNELSTATE(srcPtr);
+ ChannelState *statePtr = GET_CHANNELSTATE(srcPtr);
+ Interp *interpPtr = GET_CHANNELINTERP(srcPtr);
SET_CHANNELSTATE(copyPtr, statePtr);
+ SET_CHANNELINTERP(copyPtr, interpPtr);
Tcl_Preserve(statePtr);
copyPtr->typePtr = &tclChannelType;
}
@@ -10641,6 +10647,7 @@ SetChannelFromAny(
register Tcl_Obj *objPtr) /* The object to convert. */
{
ChannelState *statePtr;
+ Interp *interpPtr;
if (objPtr->typePtr == &tclChannelType) {
/*
@@ -10649,11 +10656,16 @@ SetChannelFromAny(
*/
statePtr = GET_CHANNELSTATE(objPtr);
+ interpPtr = GET_CHANNELINTERP(objPtr);
if (GotFlag(statePtr, CHANNEL_TAINTED|CHANNEL_CLOSED)) {
ResetFlag(statePtr, CHANNEL_TAINTED);
Tcl_Release(statePtr);
UpdateStringOfChannel(objPtr);
objPtr->typePtr = NULL;
+ } else if (interpPtr != (Interp*) interp) {
+ Tcl_Release(statePtr);
+ UpdateStringOfChannel(objPtr);
+ objPtr->typePtr = NULL;
}
}
if (objPtr->typePtr != &tclChannelType) {
@@ -10677,6 +10689,7 @@ SetChannelFromAny(
statePtr = ((Channel *) chan)->state;
Tcl_Preserve(statePtr);
SET_CHANNELSTATE(objPtr, statePtr);
+ SET_CHANNELINTERP(objPtr, interp);
objPtr->typePtr = &tclChannelType;
}
return TCL_OK;