diff options
author | davygrvy <davygrvy@pobox.com> | 2002-12-17 02:47:38 (GMT) |
---|---|---|
committer | davygrvy <davygrvy@pobox.com> | 2002-12-17 02:47:38 (GMT) |
commit | 8fd397ee9ff91c143248a1ad2d38a15501f42489 (patch) | |
tree | b0fb63ee0afd303f5cf38f33ad6b51f21b5830c1 /win/tclWinPipe.c | |
parent | 769a60101291f798e16b5919ab9f5879806ccd37 (diff) | |
download | tcl-8fd397ee9ff91c143248a1ad2d38a15501f42489.zip tcl-8fd397ee9ff91c143248a1ad2d38a15501f42489.tar.gz tcl-8fd397ee9ff91c143248a1ad2d38a15501f42489.tar.bz2 |
* generic/tclPipe.c (TclCleanupChildren):
* tests/winPipe.c:
* win/tclWinPipe.c (Tcl_WaitPid):
* win/tclWinTest.c: Gave Tcl_WaitPid the ability to return a
Win32 exception code translated into a posix style SIG*. This
allows [close] to report "CHILDKILLED" without the meaning
getting lost in a truncated exit code. In TclCleanupChildren(),
TclpGetPid() had to get moved to before Tcl_WaitPid() as the
the handle is removed from the list taking away the ability
to get the process id after the wait is done. This shouldn't
effect the unix implimentaion unless waitpid is called with
a pid of zero, meaning "any". I don't think it is..
Diffstat (limited to 'win/tclWinPipe.c')
-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 64ecf6d..a8071c0 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.31 2002/12/05 00:15:01 davygrvy Exp $ + * RCS: @(#) $Id: tclWinPipe.c,v 1.32 2002/12/17 02:47:39 davygrvy Exp $ */ #include "tclWinInt.h" @@ -2452,7 +2452,7 @@ Tcl_WaitPid( ProcInfo *infoPtr, **prevPtrPtr; DWORD flags; Tcl_Pid result; - DWORD ret; + DWORD ret, exitCode; PipeInit(); @@ -2507,9 +2507,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: + *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: + case EXCEPTION_INVALID_HANDLE: + *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; |