summaryrefslogtreecommitdiffstats
path: root/win
diff options
context:
space:
mode:
authordavygrvy <davygrvy@pobox.com>2005-04-19 16:28:22 (GMT)
committerdavygrvy <davygrvy@pobox.com>2005-04-19 16:28:22 (GMT)
commitdcd2e428a1d1f9e3e9948ec66db8fc00a50f5f78 (patch)
tree26209da071fe74735cc8b3ec35ad52bb1c9cb722 /win
parenta67b1b3bbeb88556675d7fde92fea842d50ef35f (diff)
downloadtcl-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')
-rw-r--r--win/tclWinPipe.c49
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;
}