summaryrefslogtreecommitdiffstats
path: root/generic/tclIOGT.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2014-11-06 16:24:02 (GMT)
committerdgp <dgp@users.sourceforge.net>2014-11-06 16:24:02 (GMT)
commit1db5ff8c2cde3fd48be30ff8b9ce4c121eba21f6 (patch)
treef8b76525d88e681667025f5f174e1baf8f3cd720 /generic/tclIOGT.c
parent48ab03f3cd8e637c9cdd52bdbb93737f07d2bb60 (diff)
parent559b8ab9de85a070d0dc00c5a8fb397c9baa7d6c (diff)
downloadtcl-1db5ff8c2cde3fd48be30ff8b9ce4c121eba21f6.zip
tcl-1db5ff8c2cde3fd48be30ff8b9ce4c121eba21f6.tar.gz
tcl-1db5ff8c2cde3fd48be30ff8b9ce4c121eba21f6.tar.bz2
[5adc350683] Stop Tcl forcing EOF condition on channels to be permanent.
It may be fleeting, and all parts of Tcl channel ecosystem have to deal with that. New assertions and tests to keep us on track.
Diffstat (limited to 'generic/tclIOGT.c')
-rw-r--r--generic/tclIOGT.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/generic/tclIOGT.c b/generic/tclIOGT.c
index fe0a880..7ba2f2a 100644
--- a/generic/tclIOGT.c
+++ b/generic/tclIOGT.c
@@ -187,6 +187,7 @@ struct TransformChannelData {
Tcl_Channel self; /* Our own Channel handle. */
int readIsFlushed; /* Flag to note whether in.flushProc was
* called or not. */
+ int eofPending; /* Flag: EOF seen down, not raised up */
int flags; /* Currently CHANNEL_ASYNC or zero. */
int watchMask; /* Current watch/event/interest mask. */
int mode; /* Mode of parent channel, OR'ed combination
@@ -292,6 +293,7 @@ TclChannelTransform(
Tcl_DStringInit(&ds);
Tcl_GetChannelOption(interp, chan, "-blocking", &ds);
dataPtr->readIsFlushed = 0;
+ dataPtr->eofPending = 0;
dataPtr->flags = 0;
if (ds.string[0] == '0') {
dataPtr->flags |= CHANNEL_ASYNC;
@@ -624,7 +626,7 @@ TransformInputProc(
if (toRead == 0 || dataPtr->self == NULL) {
/*
- * Catch a no-op.
+ * Catch a no-op. TODO: Is this a panic()?
*/
return 0;
}
@@ -676,6 +678,17 @@ TransformInputProc(
if (toRead <= 0) {
break;
}
+ if (dataPtr->eofPending) {
+ /*
+ * Already saw EOF from downChan; don't ask again.
+ * NOTE: Could move this up to avoid the last maxRead
+ * execution. Believe this would still be correct behavior,
+ * but the test suite tests the whole command callback
+ * sequence, so leave it unchanged for now.
+ */
+
+ break;
+ }
/*
* Get bytes from the underlying channel.
@@ -712,14 +725,7 @@ TransformInputProc(
* on the down channel.
*/
- if (dataPtr->readIsFlushed) {
- /*
- * Already flushed, nothing to do anymore.
- */
-
- break;
- }
-
+ dataPtr->eofPending = 1;
dataPtr->readIsFlushed = 1;
ExecuteCallback(dataPtr, NULL, A_FLUSH_READ, NULL, 0,
TRANSMIT_IBUF, P_PRESERVE);
@@ -747,8 +753,11 @@ TransformInputProc(
break;
}
} /* while toRead > 0 */
- ReleaseData(dataPtr);
+ if (gotBytes == 0) {
+ dataPtr->eofPending = 0;
+ }
+ ReleaseData(dataPtr);
return gotBytes;
}
@@ -859,6 +868,7 @@ TransformSeekProc(
P_NO_PRESERVE);
ResultClear(&dataPtr->result);
dataPtr->readIsFlushed = 0;
+ dataPtr->eofPending = 0;
}
ReleaseData(dataPtr);
@@ -932,6 +942,7 @@ TransformWideSeekProc(
P_NO_PRESERVE);
ResultClear(&dataPtr->result);
dataPtr->readIsFlushed = 0;
+ dataPtr->eofPending = 0;
}
ReleaseData(dataPtr);