diff options
author | andreas_kupries <akupries@shaw.ca> | 2010-03-09 21:13:13 (GMT) |
---|---|---|
committer | andreas_kupries <akupries@shaw.ca> | 2010-03-09 21:13:13 (GMT) |
commit | 9e9589c93aa74b20f3d626142697dd1687512762 (patch) | |
tree | d7537d3bde356fe98e8bbcb212ffc8f84e59dbb3 /generic/tclIORChan.c | |
parent | c06d403baef36b9cefc85590d18795a36bd0427c (diff) | |
download | tcl-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.c | 33 |
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: */ |