From 7e2fb9e70cbf48d9ab770d3a64d35e3aa745bb21 Mon Sep 17 00:00:00 2001 From: davygrvy Date: Wed, 4 Dec 2002 22:04:38 +0000 Subject: * 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. --- ChangeLog | 16 +++++++++++++++- win/tclWinPipe.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 67 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7fd238d..7992162 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2002-12-04 David Gravereaux + + * 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. + 2002-12-04 Vince Darley * generic/tclIOUtil.c: fix to redirected 'load' in virtual @@ -79,7 +93,7 @@ [Patch 561305 561301] 2) Revamps how the socket message handler thread is brought - up and down to allows for cleaner exits without the use of + up and down to allow for cleaner exits without the use of TerminateThread(). TerminateThread is evil. No attempt has been made to resolve [Bug 593810] which may need a new channel driver version for adding a registering function 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; -- cgit v0.12