summaryrefslogtreecommitdiffstats
path: root/win/tclWinPipe.c
diff options
context:
space:
mode:
authordavygrvy <davygrvy@pobox.com>2002-12-04 22:04:38 (GMT)
committerdavygrvy <davygrvy@pobox.com>2002-12-04 22:04:38 (GMT)
commit7e2fb9e70cbf48d9ab770d3a64d35e3aa745bb21 (patch)
tree1bed9c021ccaa1ad098a93249d0e2aa2591546f4 /win/tclWinPipe.c
parent8e711fbc8f9fa92e577821c9c5243bbd4c1d6a8c (diff)
downloadtcl-7e2fb9e70cbf48d9ab770d3a64d35e3aa745bb21.zip
tcl-7e2fb9e70cbf48d9ab770d3a64d35e3aa745bb21.tar.gz
tcl-7e2fb9e70cbf48d9ab770d3a64d35e3aa745bb21.tar.bz2
* win/tclWinPipe.c (Tcl_WaitPid): When a process exits with an
exception, pass this notice on to the caller with a SIG* code rather than truncating the exit code and missing the meaning. This allows TclCleanupChildren() to report "CHILDKILLED". This has a different behavior than unix in that closing the read pipe to a process sends the SIGPIPE signal which is returned as a SIGPIPE exit status. On windows, we send the process a CTRL_BREAK_EVENT and get back a CONTROL_C_EXIT which is documented to mean a SIGINT which seems wrong as a system, but is the correct exit status.
Diffstat (limited to 'win/tclWinPipe.c')
-rw-r--r--win/tclWinPipe.c57
1 files changed, 52 insertions, 5 deletions
diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c
index 2a9cfe7..acb7ca6 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.29 2002/12/04 05:41:14 davygrvy Exp $
+ * RCS: @(#) $Id: tclWinPipe.c,v 1.30 2002/12/04 22:05:18 davygrvy Exp $
*/
#include "tclWinInt.h"
@@ -2465,7 +2465,7 @@ Tcl_WaitPid(
ProcInfo *infoPtr, **prevPtrPtr;
DWORD flags;
Tcl_Pid result;
- DWORD ret;
+ DWORD ret, exitCode;
PipeInit();
@@ -2520,9 +2520,56 @@ Tcl_WaitPid(
} else {
result = 0;
}
- } else if (ret != WAIT_FAILED) {
- GetExitCodeProcess(infoPtr->hProcess, (DWORD*)statPtr);
- *statPtr = ((*statPtr << 8) & 0xff00);
+ } else if (ret == WAIT_OBJECT_0) {
+ GetExitCodeProcess(infoPtr->hProcess, &exitCode);
+ if (exitCode & 0xC0000000) {
+ /*
+ * A fatal exception occured.
+ */
+ switch (exitCode) {
+ case EXCEPTION_FLT_DENORMAL_OPERAND:
+ case EXCEPTION_FLT_DIVIDE_BY_ZERO:
+ case EXCEPTION_FLT_INEXACT_RESULT:
+ case EXCEPTION_FLT_INVALID_OPERATION:
+ case EXCEPTION_FLT_OVERFLOW:
+ case EXCEPTION_FLT_STACK_CHECK:
+ case EXCEPTION_FLT_UNDERFLOW:
+ case EXCEPTION_INT_DIVIDE_BY_ZERO:
+ case EXCEPTION_INT_OVERFLOW:
+ *statPtr = SIGFPE;
+ break;
+
+ case EXCEPTION_PRIV_INSTRUCTION:
+ case EXCEPTION_ILLEGAL_INSTRUCTION:
+ case EXCEPTION_INVALID_HANDLE:
+ *statPtr = SIGILL;
+ break;
+
+ case EXCEPTION_ACCESS_VIOLATION:
+ case EXCEPTION_DATATYPE_MISALIGNMENT:
+ case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
+ case EXCEPTION_STACK_OVERFLOW:
+ case EXCEPTION_NONCONTINUABLE_EXCEPTION:
+ case EXCEPTION_INVALID_DISPOSITION:
+ case EXCEPTION_GUARD_PAGE:
+ *statPtr = SIGSEGV;
+ break;
+
+ case CONTROL_C_EXIT:
+ *statPtr = SIGINT;
+ break;
+
+ default:
+ *statPtr = SIGABRT;
+ break;
+ }
+ } else {
+ /*
+ * Non exception, normal, exit code. Note that the exit code
+ * is truncated to a byte range.
+ */
+ *statPtr = ((exitCode << 8) & 0xff00);
+ }
result = pid;
} else {
errno = ECHILD;