diff options
author | oehhar <harald.oehlmann@elmicron.de> | 2014-10-17 10:00:39 (GMT) |
---|---|---|
committer | oehhar <harald.oehlmann@elmicron.de> | 2014-10-17 10:00:39 (GMT) |
commit | 63acce0c26f00ce8e3d4acb5840db0105f47631d (patch) | |
tree | 239e5dd2f89b978e46ca772b0d367cce522e8377 /generic/tclIO.c | |
parent | d9a8b078d1c03a51b8835666ddd27e0e54a2817d (diff) | |
parent | ceff856085045650b5b10e2d2fea1355ba78e4c4 (diff) | |
download | tcl-63acce0c26f00ce8e3d4acb5840db0105f47631d.zip tcl-63acce0c26f00ce8e3d4acb5840db0105f47631d.tar.gz tcl-63acce0c26f00ce8e3d4acb5840db0105f47631d.tar.bz2 |
Merge trunk
Diffstat (limited to 'generic/tclIO.c')
-rw-r--r-- | generic/tclIO.c | 44 |
1 files changed, 34 insertions, 10 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c index dcde8d1..9283bf5 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -3894,7 +3894,10 @@ Tcl_Write( if (srcLen < 0) { srcLen = strlen(src); } - return WriteBytes(chanPtr, src, srcLen); + if (WriteBytes(chanPtr, src, srcLen) < 0) { + return -1; + } + return srcLen; } /* @@ -6046,12 +6049,11 @@ ReadChars( /* * We read more chars than allowed. Reset limits to * prevent that and try again. Don't forget the extra - * padding of TCL_UTF_MAX - 1 bytes demanded by the + * padding of TCL_UTF_MAX bytes demanded by the * Tcl_ExternalToUtf() call! */ - dstLimit = Tcl_UtfAtIndex(dst, charsToRead + 1) - + TCL_UTF_MAX - 1 - dst; + dstLimit = Tcl_UtfAtIndex(dst, charsToRead) + TCL_UTF_MAX - dst; statePtr->flags = savedFlags; statePtr->inputEncodingFlags = savedIEFlags; statePtr->inputEncodingState = savedState; @@ -9021,7 +9023,7 @@ MBRead( } code = GetInput(inStatePtr->topChanPtr); - if (code == 0) { + if (code == 0 || GotFlag(inStatePtr, CHANNEL_BLOCKED)) { return TCL_OK; } else { MBError(csPtr, TCL_READABLE, code); @@ -9271,6 +9273,10 @@ CopyData( csPtr); } if (size == 0) { + if (!GotFlag(inStatePtr, CHANNEL_NONBLOCKING)) { + /* We allowed a short read. Keep trying. */ + continue; + } if (bufObj != NULL) { TclDecrRefCount(bufObj); bufObj = NULL; @@ -9503,21 +9509,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; |