summaryrefslogtreecommitdiffstats
path: root/generic/tclIO.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2014-04-16 20:11:05 (GMT)
committerdgp <dgp@users.sourceforge.net>2014-04-16 20:11:05 (GMT)
commite827fc803e4afed0de2b1f9b37cd53379ef7118b (patch)
tree0cb51679567890cb745a261b7066f96262f8b372 /generic/tclIO.c
parent60a84571795909d2b51dff06349107716ae3ab6d (diff)
parentca6f13bb3001d560ccd18ff40400afca249ebe28 (diff)
downloadtcl-e827fc803e4afed0de2b1f9b37cd53379ef7118b.zip
tcl-e827fc803e4afed0de2b1f9b37cd53379ef7118b.tar.gz
tcl-e827fc803e4afed0de2b1f9b37cd53379ef7118b.tar.bz2
merge 8.5
Diffstat (limited to 'generic/tclIO.c')
-rw-r--r--generic/tclIO.c36
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);
}