diff options
author | davygrvy <davygrvy@pobox.com> | 2005-04-19 16:28:22 (GMT) |
---|---|---|
committer | davygrvy <davygrvy@pobox.com> | 2005-04-19 16:28:22 (GMT) |
commit | dcd2e428a1d1f9e3e9948ec66db8fc00a50f5f78 (patch) | |
tree | 26209da071fe74735cc8b3ec35ad52bb1c9cb722 | |
parent | a67b1b3bbeb88556675d7fde92fea842d50ef35f (diff) | |
download | tcl-dcd2e428a1d1f9e3e9948ec66db8fc00a50f5f78.zip tcl-dcd2e428a1d1f9e3e9948ec66db8fc00a50f5f78.tar.gz tcl-dcd2e428a1d1f9e3e9948ec66db8fc00a50f5f78.tar.bz2 |
* win/tclWinPipe.c: The pipe channel driver now respects
the -blocking option when closing. The windows pipe driver
now has the same behavior as the UNIX side. This change is
to avoid a hung shell when exiting due to open pipes that
refuse to close in a graceful manner.
* doc/open.n: Added a note about -blocking 0 and lack of
exit status as it had never been documented. [Bug 947693]
***POTENTIAL INCOMPATIBILITY***
Scripts that use async pipes on windows, must (like the
UNIX side) set -blocking to 1 before calling [close] to
receive the exit status.
* tests/winPipe.test (winpipe-6.1/2): added 'fconfigure $f
-blocking 1' so the exit status can be acquired.
-rw-r--r-- | doc/open.n | 5 | ||||
-rw-r--r-- | tests/winPipe.test | 4 | ||||
-rw-r--r-- | win/tclWinPipe.c | 49 |
3 files changed, 38 insertions, 20 deletions
@@ -5,7 +5,7 @@ '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" -'\" RCS: @(#) $Id: open.n,v 1.16.2.2 2004/10/27 14:23:57 dkf Exp $ +'\" RCS: @(#) $Id: open.n,v 1.16.2.3 2005/04/19 16:30:21 davygrvy Exp $ '\" .so man.macros .TH open n 8.3 Tcl "Tcl Built-In Commands" @@ -136,7 +136,8 @@ command, using the channel id returned by \fBopen\fR as argument. If the command (or one of the commands) executed in the command pipeline returns an error (according to the definition in \fBexec\fR), a Tcl error is generated when \fBclose\fR is called on the channel -(similar to the \fBclose\fR command.) +unless the pipeline is in non-blocking mode then no exit status is +returned (a silent \fBclose\fR with -blocking 0). .PP It is often useful to use the \fBfileevent\fR command with pipelines so other processing may happen at the same time as running the command diff --git a/tests/winPipe.test b/tests/winPipe.test index 4cc6e26..34de9bb 100644 --- a/tests/winPipe.test +++ b/tests/winPipe.test @@ -12,7 +12,7 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # -# RCS: @(#) $Id: winPipe.test,v 1.22.2.2 2004/10/28 00:01:12 dgp Exp $ +# RCS: @(#) $Id: winPipe.test,v 1.22.2.3 2005/04/19 16:28:34 davygrvy Exp $ package require tcltest namespace import -force ::tcltest::* @@ -295,6 +295,7 @@ test winpipe-6.1 {PipeSetupProc & PipeCheckProc: read threads} \ lappend x [read $f] after 100 { lappend x timeout } vwait x + fconfigure $f -blocking 1 lappend x [catch {close $f} msg] $msg } {writable timeout readable {foobar } timeout 1 stderr32} @@ -309,6 +310,7 @@ test winpipe-6.2 {PipeSetupProc & PipeCheckProc: write threads} \ flush $f after 100 { lappend x timeout } vwait x + fconfigure $f -blocking 1 lappend x [catch {close $f} msg] $msg } {writable timeout 0 {}} diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index 57858f0..0206ac5 100644 --- a/win/tclWinPipe.c +++ b/win/tclWinPipe.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclWinPipe.c,v 1.33.2.9 2005/01/27 22:53:37 andreas_kupries Exp $ + * RCS: @(#) $Id: tclWinPipe.c,v 1.33.2.10 2005/04/19 16:28:22 davygrvy Exp $ */ #include "tclWinInt.h" @@ -2046,27 +2046,42 @@ PipeClose2Proc( } } - /* - * Wrap the error file into a channel and give it to the cleanup - * routine. - */ + if ((pipePtr->flags & PIPE_ASYNC) || TclInExit()) { + /* + * If the channel is non-blocking or Tcl is being cleaned up, + * just detach the children PIDs, reap them (important if we are + * in a dynamic load module), and discard the errorFile. + */ - if (pipePtr->errorFile) { - WinFile *filePtr; + Tcl_DetachPids(pipePtr->numPids, pipePtr->pidPtr); + Tcl_ReapDetachedProcs(); - filePtr = (WinFile*)pipePtr->errorFile; - errChan = Tcl_MakeFileChannel((ClientData) filePtr->handle, - TCL_READABLE); - ckfree((char *) filePtr); + if (pipePtr->errorFile) { + TclpCloseFile(pipePtr->errorFile); + } } else { - errChan = NULL; - } + /* + * Wrap the error file into a channel and give it to the cleanup + * routine. + */ + + if (pipePtr->errorFile) { + WinFile *filePtr; - result = TclCleanupChildren(interp, pipePtr->numPids, pipePtr->pidPtr, - errChan); + filePtr = (WinFile*)pipePtr->errorFile; + errChan = Tcl_MakeFileChannel((ClientData) filePtr->handle, + TCL_READABLE); + ckfree((char *) filePtr); + } else { + errChan = NULL; + } + + result = TclCleanupChildren(interp, pipePtr->numPids, + pipePtr->pidPtr, errChan); + } if (pipePtr->numPids > 0) { - ckfree((char *) pipePtr->pidPtr); + ckfree((char *) pipePtr->pidPtr); } if (pipePtr->writeBuf != NULL) { @@ -2076,7 +2091,7 @@ PipeClose2Proc( ckfree((char*) pipePtr); if (errorCode == 0) { - return result; + return result; } return errorCode; } |