summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tclIO.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index a329fbb..28e7297 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -6040,11 +6040,7 @@ DoReadChars(
if (GotFlag(statePtr, CHANNEL_ENCODING_ERROR)
&& !GotFlag(statePtr, CHANNEL_STICKY_EOF)
- && !GotFlag(statePtr, CHANNEL_NONBLOCKING)) {
- /* Channel is blocking. Return an error so that callers
- * like [read] can return an error.
- */
- Tcl_SetErrno(EILSEQ);
+ && (!GotFlag(statePtr, CHANNEL_NONBLOCKING))) {
goto finish;
}
}
@@ -6089,7 +6085,7 @@ finish:
}
/*
- * Regenerate the top channel, in case it was changed due to
+ * Regenerate chanPtr in case it was changed due to
* self-modifying reflected transforms.
*/
@@ -6111,8 +6107,14 @@ finish:
assert(!(GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED)
== (CHANNEL_EOF|CHANNEL_BLOCKED)));
UpdateInterest(chanPtr);
+
+ /* This must comes after UpdateInterest(), which may set errno */
if (GotFlag(statePtr, CHANNEL_ENCODING_ERROR)
&& (!copied || !GotFlag(statePtr, CHANNEL_NONBLOCKING))) {
+ /* Channel either is blocking or is nonblocking with no data
+ * succesfully red before the error. Return an error so that callers
+ * like [read] can also return an error.
+ */
Tcl_SetErrno(EILSEQ);
copied = -1;
}