diff options
author | davygrvy <davygrvy@pobox.com> | 2002-12-04 22:04:38 (GMT) |
---|---|---|
committer | davygrvy <davygrvy@pobox.com> | 2002-12-04 22:04:38 (GMT) |
commit | 7e2fb9e70cbf48d9ab770d3a64d35e3aa745bb21 (patch) | |
tree | 1bed9c021ccaa1ad098a93249d0e2aa2591546f4 /win | |
parent | 8e711fbc8f9fa92e577821c9c5243bbd4c1d6a8c (diff) | |
download | tcl-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')
-rw-r--r-- | win/tclWinPipe.c | 57 |
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; |