summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--generic/tclIORChan.c15
-rw-r--r--tests/ioCmd.test4
3 files changed, 22 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 774b44e..f91bead 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
2008-04-04 Andreas Kupries <andreask@activestate.com>
+ * generic/tclIORChan.c (ReflectOutput): Allow zero return from
+ write when input was zero-length anyway. Otherwise keept it an
+ error, and separate the message from 'written too much'.
+
+ * tests/ioCmd.test (iocmd-24.6): Testcase updated for changed
+ message.
+
* generic/tclIORChan.c (ReflectClose): Added missing removal of
the now closed channel from the reflection map. Before we could
crash the system by invoking 'chan postevent' on a closed
diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c
index 905a773..157e712 100644
--- a/generic/tclIORChan.c
+++ b/generic/tclIORChan.c
@@ -15,7 +15,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclIORChan.c,v 1.28.2.1 2008/04/04 16:45:50 andreas_kupries Exp $
+ * RCS: @(#) $Id: tclIORChan.c,v 1.28.2.2 2008/04/04 17:19:42 andreas_kupries Exp $
*/
#include <tclInt.h>
@@ -434,6 +434,7 @@ static const char *msg_read_unsup = "{read not supported by Tcl driver}";
static const char *msg_read_toomuch = "{read delivered more than requested}";
static const char *msg_write_unsup = "{write not supported by Tcl driver}";
static const char *msg_write_toomuch = "{write wrote more than requested}";
+static const char *msg_write_nothing = "{write wrote nothing}";
static const char *msg_seek_beforestart = "{Tried to seek before origin}";
#ifdef TCL_THREADS
static const char *msg_send_originlost = "{Origin thread lost}";
@@ -1290,7 +1291,17 @@ ReflectOutput(
Tcl_DecrRefCount(resObj); /* Remove reference held from invoke */
- if ((written == 0) || (toWrite < written)) {
+ if ((written == 0) && (toWrite > 0)) {
+ /*
+ * The handler claims to have written nothing of what it was
+ * given. That is bad.
+ */
+
+ SetChannelErrorStr(rcPtr->chan, msg_write_nothing);
+ *errorCodePtr = EINVAL;
+ return -1;
+ }
+ if (toWrite < written) {
/*
* The handler claims to have written more than it was given. That is
* bad. Note that the I/O core would crash if we were to return this
diff --git a/tests/ioCmd.test b/tests/ioCmd.test
index 024e622..fcdc326 100644
--- a/tests/ioCmd.test
+++ b/tests/ioCmd.test
@@ -13,7 +13,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: ioCmd.test,v 1.36.2.1 2008/04/04 16:45:51 andreas_kupries Exp $
+# RCS: @(#) $Id: ioCmd.test,v 1.36.2.2 2008/04/04 17:19:43 andreas_kupries Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest 2
@@ -1039,7 +1039,7 @@ test iocmd-24.6 {chan write, bad result, zero-length write} -match glob -body {
close $c
rename foo {}
set res
-} -result {{write rc* snarf} 1 {write wrote more than requested}}
+} -result {{write rc* snarf} 1 {write wrote nothing}}
test iocmd-24.7 {chan write, failed write, error return} -match glob -body {
set res {}
proc foo {args} {oninit; onfinal; track; return -code error BOOM!}