summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tclIO.c27
-rw-r--r--tests/ioCmd.test3
2 files changed, 27 insertions, 3 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index b06c14d..0f2aa28 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -2453,13 +2453,35 @@ FlushChannel(
*/
if ((errorCode == EWOULDBLOCK) || (errorCode == EAGAIN)) {
- /*
- * This used to check for CHANNEL_NONBLOCKING, and panic if
+
+
+ /* PREVIOUS RATIONALE -- UNDER EVALUATION
+ *
+ * This used to check for CHANNEL_NONBLOCKING, and panic if
* the channel was blocking. However, it appears that setting
* stdin to -blocking 0 has some effect on the stdout when
* it's a tty channel (dup'ed underneath)
*/
+ /* NEW RATIONALE -- UNDER EVALUATION
+ *
+ * We explicitly disallow EAGAIN/EWOULDBLOCK for blocking
+ * channels, but throw an error instead of panicking, since
+ * this may be a simple scripting error in a refelected
+ * channel.
+ */
+
+ if (!GotFlag(statePtr, CHANNEL_NONBLOCKING)) {
+ //Tcl_Panic("EAGAIN Illegally thrown by blocking channel");
+
+ Tcl_SetChannelError((Tcl_Channel) chanPtr,
+ Tcl_ObjPrintf("{EAGAIN Illegally thrown by blocking channel \"%s\"}",
+ Tcl_GetChannelName((Tcl_Channel)chanPtr)));
+ errorCode=EINVAL;
+ DiscardOutputQueued(statePtr);
+ goto done;
+ }
+
if (!GotFlag(statePtr, BG_FLUSH_SCHEDULED)) {
SetFlag(statePtr, BG_FLUSH_SCHEDULED);
UpdateInterest(chanPtr);
@@ -2524,7 +2546,6 @@ FlushChannel(
* When we get an error we throw away all the output currently
* queued.
*/
-
DiscardOutputQueued(statePtr);
continue;
} else {
diff --git a/tests/ioCmd.test b/tests/ioCmd.test
index 4c08229..6b1da73 100644
--- a/tests/ioCmd.test
+++ b/tests/ioCmd.test
@@ -2575,6 +2575,7 @@ test iocmd.tf-24.15 {chan write, EAGAIN means that writing is not allowed at thi
set res
} -cleanup {
proc foo {args} {onfinal; set ::done-24.15 1; return 3}
+ after 1000 {set ::done-24.15 2}
vwait done-24.15
rename foo {}
unset res
@@ -2603,10 +2604,12 @@ test iocmd.tf-24.16 {chan write, note the background flush setup by close due to
proc foo {args} { onfinal; note BG ; track ; set ::endbody-24.16 1}
# Flush (sic!) the event-queue to capture the write from a
# BG-flush.
+ after 1000 {set ::endbody-24.16 2}
vwait endbody-24.16
set res
} -cleanup {
proc foo {args} {onfinal; set ::done-24.16 1; return 3}
+ after 1000 {set ::done-24.16 2}
vwait done-24.16
rename foo {}
unset res