summaryrefslogtreecommitdiffstats
path: root/generic/tclIORChan.c
diff options
context:
space:
mode:
authorandreas_kupries <akupries@shaw.ca>2010-03-09 21:13:13 (GMT)
committerandreas_kupries <akupries@shaw.ca>2010-03-09 21:13:13 (GMT)
commit9e9589c93aa74b20f3d626142697dd1687512762 (patch)
treed7537d3bde356fe98e8bbcb212ffc8f84e59dbb3 /generic/tclIORChan.c
parentc06d403baef36b9cefc85590d18795a36bd0427c (diff)
downloadtcl-9e9589c93aa74b20f3d626142697dd1687512762.zip
tcl-9e9589c93aa74b20f3d626142697dd1687512762.tar.gz
tcl-9e9589c93aa74b20f3d626142697dd1687512762.tar.bz2
* generic/tclIORChan.c: [Bug 2936225]: Thanks to Alexandre Ferrieux
* doc/refchan.n: <ferrieux@users.sourceforge.net> for debugging and fixing * tests/ioCmd.test: the problem. It is the write-side equivalent to the bug fixed 2009-08-06.
Diffstat (limited to 'generic/tclIORChan.c')
-rw-r--r--generic/tclIORChan.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c
index 305b3ad..f483870 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.8 2009/10/07 17:11:40 andreas_kupries Exp $
+ * RCS: @(#) $Id: tclIORChan.c,v 1.28.2.9 2010/03/09 21:13:13 andreas_kupries Exp $
*/
#include <tclInt.h>
@@ -1327,8 +1327,13 @@ ReflectOutput(
ForwardOpToOwnerThread(rcPtr, ForwardedOutput, &p);
if (p.base.code != TCL_OK) {
- PassReceivedError(rcPtr->chan, &p);
- *errorCodePtr = EINVAL;
+ if (p.base.code < 0) {
+ /* No error message, this is an errno signal. */
+ *errorCodePtr = -p.base.code;
+ } else {
+ PassReceivedError(rcPtr->chan, &p);
+ *errorCodePtr = EINVAL;
+ }
p.output.toWrite = -1;
} else {
*errorCodePtr = EOK;
@@ -1343,6 +1348,14 @@ ReflectOutput(
bufObj = Tcl_NewByteArrayObj((unsigned char *) buf, toWrite);
if (InvokeTclMethod(rcPtr, "write", bufObj, NULL, &resObj) != TCL_OK) {
+ int code = ErrnoReturn(rcPtr, resObj);
+
+ if (code < 0) {
+ Tcl_DecrRefCount(resObj); /* Remove reference held from invoke */
+ *errorCodePtr = -code;
+ return -1;
+ }
+
Tcl_SetChannelError(rcPtr->chan, resObj);
Tcl_DecrRefCount(resObj); /* Remove reference held from invoke */
*errorCodePtr = EINVAL;
@@ -2291,8 +2304,8 @@ InvokeTclMethod(
* None.
*
* Users:
- * Currently only ReflectInput(), to enable the signaling of EAGAIN.
- * by non-blocking channels at buffer-empty, but not EOF.
+ * ReflectInput/Output(), to enable the signaling of EAGAIN
+ * on 0-sized short reads/writes.
*
*----------------------------------------------------------------------
*/
@@ -2846,7 +2859,13 @@ ForwardProc(
paramPtr->output.buf, paramPtr->output.toWrite);
if (InvokeTclMethod(rcPtr, "write", bufObj, NULL, &resObj) != TCL_OK) {
- ForwardSetObjError(paramPtr, resObj);
+ int code = ErrnoReturn(rcPtr, resObj);
+
+ if (code < 0) {
+ paramPtr->base.code = code;
+ } else {
+ ForwardSetObjError(paramPtr, resObj);
+ }
paramPtr->output.toWrite = -1;
} else {
/*
@@ -3088,5 +3107,7 @@ ForwardSetObjError(
* mode: c
* c-basic-offset: 4
* fill-column: 78
+ * tab-width: 8
+ * indent-tabs-mode: nil
* End:
*/