diff options
author | andreas_kupries <akupries@shaw.ca> | 2008-12-11 17:30:18 (GMT) |
---|---|---|
committer | andreas_kupries <akupries@shaw.ca> | 2008-12-11 17:30:18 (GMT) |
commit | 6cb99f7bf8a960b9c8db1d06c4509fea270989b1 (patch) | |
tree | 84e713e17a14c7002afd51995234808c2c8b99db /generic/tclIO.c | |
parent | 1e9af660c1936aa10a345ac8f0ee41f74143c698 (diff) | |
download | tcl-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.c | 17 |
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; |