summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2014-03-28 20:29:03 (GMT)
committerdgp <dgp@users.sourceforge.net>2014-03-28 20:29:03 (GMT)
commitd3b630496048c958812ce8924b0b8cfc41557b39 (patch)
tree1d21904caed29ddac825462a068c419804460557
parente29ec23cfcb4b4a117052e22d9c8b4377c5acad1 (diff)
parent06f376eefe2af7c3eb3f8131dacd6bc296a2fb71 (diff)
downloadtcl-d3b630496048c958812ce8924b0b8cfc41557b39.zip
tcl-d3b630496048c958812ce8924b0b8cfc41557b39.tar.gz
tcl-d3b630496048c958812ce8924b0b8cfc41557b39.tar.bz2
Merge minimal fix for iocmd-23.11.
Note that top channel regeneration is removed, so that Preserve/Release call pairs are sure to operate on the same pointers. Other bug fixes may need to change that.
-rw-r--r--generic/tclIO.c38
-rw-r--r--generic/tclIORChan.c2
-rw-r--r--tests/ioCmd.test3
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