summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2014-10-10 18:24:32 (GMT)
committerdgp <dgp@users.sourceforge.net>2014-10-10 18:24:32 (GMT)
commit1159aa03c57e16b943f56f65272a590c5b1f0d50 (patch)
tree4edc380d2309a8614af4d5922f663170cd99ae16
parent7652b23c6d792756ea4ca43dfdf7aed78db58d72 (diff)
downloadtcl-1159aa03c57e16b943f56f65272a590c5b1f0d50.zip
tcl-1159aa03c57e16b943f56f65272a590c5b1f0d50.tar.gz
tcl-1159aa03c57e16b943f56f65272a590c5b1f0d50.tar.bz2
[ed29c4da21] Don't let BLOCKED state get converted into a channel error.
-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;