summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@noemail.net>2014-10-10 18:24:32 (GMT)
committerdgp <dgp@noemail.net>2014-10-10 18:24:32 (GMT)
commita1cf35d69047b7e6c66bc26dfd17fd1d2a8bdd9e (patch)
tree4edc380d2309a8614af4d5922f663170cd99ae16
parentfb238394cef4806be7ccc3e75f5120900dc04944 (diff)
downloadtcl-a1cf35d69047b7e6c66bc26dfd17fd1d2a8bdd9e.zip
tcl-a1cf35d69047b7e6c66bc26dfd17fd1d2a8bdd9e.tar.gz
tcl-a1cf35d69047b7e6c66bc26dfd17fd1d2a8bdd9e.tar.bz2
[ed29c4da21] Don't let BLOCKED state get converted into a channel error.
FossilOrigin-Name: a0b44a3c1d6bfd1ecee69ab1ad35fea37c188e3e
-rw-r--r--generic/tclIO.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 3119db5..2fd3792 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -8853,21 +8853,39 @@ DoRead(
}
/*
- * If there is not enough data in the buffers to possibly
- * complete the read, then go get more.
+ * Don't read more data if we have what we need.
*/
- if (bufPtr == NULL || BytesLeft(bufPtr) < bytesToRead) {
+ while (!bufPtr || /* We got no buffer! OR */
+ (!IsBufferFull(bufPtr) && /* Our buffer has room AND */
+ (BytesLeft(bufPtr) < bytesToRead) ) ) {
+ /* Not enough bytes in it
+ * yet to fill the dst */
+ int code;
+
moreData:
- if (GetInput(chanPtr)) {
+ code = GetInput(chanPtr);
+ bufPtr = statePtr->inQueueHead;
+
+ assert (bufPtr != NULL);
+
+ if (GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED)) {
+ /* Further reads cannot do any more */
+ break;
+ }
+
+ if (code) {
/* Read error */
UpdateInterest(chanPtr);
TclChannelRelease((Tcl_Channel)chanPtr);
return -1;
}
- bufPtr = statePtr->inQueueHead;
+
+ assert (IsBufferFull(bufPtr));
}
+ assert (bufPtr != NULL);
+
bytesRead = BytesLeft(bufPtr);
bytesWritten = bytesToRead;