summaryrefslogtreecommitdiffstats
path: root/generic/tclIORChan.c
diff options
context:
space:
mode:
authorandreas_kupries <akupries@shaw.ca>2010-03-09 21:15:18 (GMT)
committerandreas_kupries <akupries@shaw.ca>2010-03-09 21:15:18 (GMT)
commit2c4e9fc134585c9dbbd25671018e100165ad1b63 (patch)
tree724d8a71a5b1260db148bd7234a41effc7475305 /generic/tclIORChan.c
parent2867759e778d170453f568cec080f7f2256aa62f (diff)
downloadtcl-2c4e9fc134585c9dbbd25671018e100165ad1b63.zip
tcl-2c4e9fc134585c9dbbd25671018e100165ad1b63.tar.gz
tcl-2c4e9fc134585c9dbbd25671018e100165ad1b63.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 3139268..50374a5 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.45 2010/02/24 10:45:04 dkf Exp $
+ * RCS: @(#) $Id: tclIORChan.c,v 1.46 2010/03/09 21:15:19 andreas_kupries Exp $
*/
#include <tclInt.h>
@@ -1331,8 +1331,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;
@@ -1347,6 +1352,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;
@@ -2295,8 +2308,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.
*
*----------------------------------------------------------------------
*/
@@ -2857,7 +2870,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 {
/*
@@ -3099,5 +3118,7 @@ ForwardSetObjError(
* mode: c
* c-basic-offset: 4
* fill-column: 78
+ * tab-width: 8
+ * indent-tabs-mode: nil
* End:
*/