diff options
author | andreas_kupries <akupries@shaw.ca> | 2010-03-09 21:15:18 (GMT) |
---|---|---|
committer | andreas_kupries <akupries@shaw.ca> | 2010-03-09 21:15:18 (GMT) |
commit | 2c4e9fc134585c9dbbd25671018e100165ad1b63 (patch) | |
tree | 724d8a71a5b1260db148bd7234a41effc7475305 /generic/tclIORChan.c | |
parent | 2867759e778d170453f568cec080f7f2256aa62f (diff) | |
download | tcl-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.c | 33 |
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: */ |