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 /win/tclWinPipe.c | |
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.
Diffstat (limited to 'win/tclWinPipe.c')
-rw-r--r-- | win/tclWinPipe.c | 49 |
1 files changed, 32 insertions, 17 deletions
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; } |