diff options
author | dgp <dgp@users.sourceforge.net> | 2014-04-16 20:11:05 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2014-04-16 20:11:05 (GMT) |
commit | e827fc803e4afed0de2b1f9b37cd53379ef7118b (patch) | |
tree | 0cb51679567890cb745a261b7066f96262f8b372 /generic/tclIO.c | |
parent | 60a84571795909d2b51dff06349107716ae3ab6d (diff) | |
parent | ca6f13bb3001d560ccd18ff40400afca249ebe28 (diff) | |
download | tcl-e827fc803e4afed0de2b1f9b37cd53379ef7118b.zip tcl-e827fc803e4afed0de2b1f9b37cd53379ef7118b.tar.gz tcl-e827fc803e4afed0de2b1f9b37cd53379ef7118b.tar.bz2 |
merge 8.5
Diffstat (limited to 'generic/tclIO.c')
-rw-r--r-- | generic/tclIO.c | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c index e7653f6..2b0a28b 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -3209,7 +3209,17 @@ Tcl_Close( Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_PosixError(interp), -1)); } - flushcode = -1; + return TCL_ERROR; + } + /* + * Bug 97069ea11a: set error message if a flush code is set and no error + * message set up to now. + */ + if (flushcode != 0 && interp != NULL + && 0 == Tcl_GetCharLength(Tcl_GetObjResult(interp)) ) { + Tcl_SetErrno(flushcode); + Tcl_SetObjResult(interp, + Tcl_NewStringObj(Tcl_PosixError(interp), -1)); } if ((flushcode != 0) || (result != 0)) { return TCL_ERROR; @@ -3850,6 +3860,7 @@ Tcl_GetsObj( */ chanPtr = statePtr->topChanPtr; + Tcl_Preserve(chanPtr); bufPtr = statePtr->inQueueHead; encoding = statePtr->encoding; @@ -4142,6 +4153,7 @@ Tcl_GetsObj( done: UpdateInterest(chanPtr); + Tcl_Release(chanPtr); return copiedTotal; } @@ -4187,6 +4199,7 @@ TclGetsObjBinary( */ chanPtr = statePtr->topChanPtr; + Tcl_Preserve(chanPtr); bufPtr = statePtr->inQueueHead; @@ -4386,6 +4399,7 @@ TclGetsObjBinary( done: UpdateInterest(chanPtr); + Tcl_Release(chanPtr); return copiedTotal; } @@ -4857,6 +4871,7 @@ Tcl_ReadRaw( * requests more bytes. */ + Tcl_Preserve(chanPtr); for (copied = 0; copied < bytesToRead; copied += copiedNow) { copiedNow = CopyBuffer(chanPtr, bufPtr + copied, bytesToRead - copied); @@ -4907,7 +4922,7 @@ Tcl_ReadRaw( * over EAGAIN/WOULDBLOCK handling. */ - return copied; + goto done; } SetFlag(statePtr, CHANNEL_BLOCKED); @@ -4915,14 +4930,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; } @@ -5031,6 +5049,7 @@ DoReadChars( chanPtr = statePtr->topChanPtr; encoding = statePtr->encoding; factor = UTF_EXPANSION_FACTOR; + Tcl_Preserve(chanPtr); binaryMode = (encoding == NULL) && (statePtr->inputTranslation == TCL_TRANSLATE_LF) @@ -5113,6 +5132,7 @@ DoReadChars( done: UpdateInterest(chanPtr); + Tcl_Release(chanPtr); return copied; } @@ -7587,6 +7607,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. @@ -8651,6 +8676,7 @@ DoRead( ChannelState *statePtr = chanPtr->state; char *p = dst; + Tcl_Preserve(chanPtr); while (bytesToRead) { /* * Each pass through the loop is intended to process up to @@ -8690,6 +8716,7 @@ DoRead( if (code) { /* Read error */ UpdateInterest(chanPtr); + Tcl_Release(chanPtr); return -1; } @@ -8784,6 +8811,7 @@ DoRead( } } + Tcl_Release(chanPtr); return (int)(p - dst); } |