diff options
-rw-r--r-- | generic/tclIO.c | 38 | ||||
-rw-r--r-- | generic/tclIORChan.c | 2 | ||||
-rw-r--r-- | tests/ioCmd.test | 3 |
3 files changed, 31 insertions, 12 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c index ff975c3..6793320 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -4261,6 +4261,7 @@ Tcl_GetsObj( */ chanPtr = statePtr->topChanPtr; + Tcl_Preserve(chanPtr); bufPtr = statePtr->inQueueHead; encoding = statePtr->encoding; @@ -4493,8 +4494,9 @@ Tcl_GetsObj( * Regenerate the top channel, in case it was changed due to * self-modifying reflected transforms. */ - + /* chanPtr = statePtr->topChanPtr; + */ bufPtr = gs.bufPtr; if (bufPtr == NULL) { @@ -4528,9 +4530,9 @@ Tcl_GetsObj( * Regenerate the top channel, in case it was changed due to * self-modifying reflected transforms. */ - + /* chanPtr = statePtr->topChanPtr; - + */ bufPtr = statePtr->inQueueHead; if (bufPtr == NULL) { Tcl_Panic("Tcl_GetsObj: restore reached with bufPtr==NULL"); @@ -4570,10 +4572,11 @@ Tcl_GetsObj( * Regenerate the top channel, in case it was changed due to * self-modifying reflected transforms. */ - + /* chanPtr = statePtr->topChanPtr; - + */ UpdateInterest(chanPtr); + Tcl_Release(chanPtr); return copiedTotal; } @@ -4619,6 +4622,7 @@ TclGetsObjBinary( */ chanPtr = statePtr->topChanPtr; + Tcl_Preserve(chanPtr); bufPtr = statePtr->inQueueHead; @@ -4822,6 +4826,7 @@ TclGetsObjBinary( done: UpdateInterest(chanPtr); + Tcl_Release(chanPtr); return copiedTotal; } @@ -5294,6 +5299,7 @@ Tcl_ReadRaw( * requests more bytes. */ + Tcl_Preserve(chanPtr); for (copied = 0; copied < bytesToRead; copied += copiedNow) { copiedNow = CopyBuffer(chanPtr, bufPtr + copied, bytesToRead - copied); @@ -5376,7 +5382,7 @@ Tcl_ReadRaw( * over EAGAIN/WOULDBLOCK handling. */ - return copied; + goto done; } SetFlag(statePtr, CHANNEL_BLOCKED); @@ -5384,14 +5390,17 @@ Tcl_ReadRaw( } Tcl_SetErrno(result); - return -1; + copied = -1; + goto done; } - return copied + nread; + copied += nread; + goto done; } } done: + Tcl_Release(chanPtr); return copied; } @@ -5499,6 +5508,7 @@ DoReadChars( chanPtr = statePtr->topChanPtr; encoding = statePtr->encoding; factor = UTF_EXPANSION_FACTOR; + Tcl_Preserve(chanPtr); if (appendFlag == 0) { if (encoding == NULL) { @@ -5590,10 +5600,11 @@ DoReadChars( * Regenerate the top channel, in case it was changed due to * self-modifying reflected transforms. */ - + /* chanPtr = statePtr->topChanPtr; - + */ UpdateInterest(chanPtr); + Tcl_Release(chanPtr); return copied; } @@ -8102,6 +8113,11 @@ UpdateInterest( /* State info for channel */ int mask = statePtr->interestMask; + if (chanPtr->typePtr == NULL) { + /* Do not update interest on a closed channel */ + return; + } + /* * If there are flushed buffers waiting to be written, then we need to * watch for the channel to become writable. @@ -9205,6 +9221,7 @@ DoRead( * operation. */ + Tcl_Preserve(chanPtr); if (!GotFlag(statePtr, CHANNEL_STICKY_EOF)) { ResetFlag(statePtr, CHANNEL_EOF); } @@ -9245,6 +9262,7 @@ DoRead( done: UpdateInterest(chanPtr); + Tcl_Release(chanPtr); return copied; } diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index cb0282a..a09a7a6 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -586,6 +586,7 @@ TclChanCreateObjCmd( chan = Tcl_CreateChannel(&tclRChannelType, TclGetString(rcId), rcPtr, mode); rcPtr->chan = chan; + Tcl_Preserve(chan); chanPtr = (Channel *) chan; /* @@ -2306,6 +2307,7 @@ FreeReflectedChannel( ckfree(chanPtr->typePtr); chanPtr->typePtr = NULL; } + Tcl_Release(chanPtr); FreeReflectedChannelArgs(rcPtr); diff --git a/tests/ioCmd.test b/tests/ioCmd.test index e3776bf..a150d59 100644 --- a/tests/ioCmd.test +++ b/tests/ioCmd.test @@ -1062,10 +1062,9 @@ test iocmd-23.11 {chan read, close pulls the rug out} -match glob -body { } set c [chan create {r} foo] note [read $c] - close $c rename foo {} set res -} -result {{read rc* 4096} {read rc* 4096} snarfsnarf} +} -result {{read rc* 4096} {}} # --- === *** ########################### # method write |