From 0c988adc2fbfe2e8803d169aaf90abccf11842a7 Mon Sep 17 00:00:00 2001 From: davygrvy Date: Sun, 30 May 2004 21:57:09 +0000 Subject: * win/tclWinPipe.c: * win/tclWinPort.h: Reworked the win implementation of Tcl_WaitPid to support exitcodes in the 'signed short' range. Even though this range is non-portable, it is valid on windows. Detection of exception codes are now more accurate. Previously, an application that exited with ExitProcess((DWORD)-1); was improperly reported as exiting with SIGABRT. --- win/tclWinPipe.c | 100 +++++++++++++++++++++++++++++++------------------------ win/tclWinPort.h | 16 +++++++-- 2 files changed, 70 insertions(+), 46 deletions(-) diff --git a/win/tclWinPipe.c b/win/tclWinPipe.c index 9653545..536a730 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.47 2004/05/10 21:50:37 davygrvy Exp $ + * RCS: @(#) $Id: tclWinPipe.c,v 1.48 2004/05/30 21:57:09 davygrvy Exp $ */ #include "tclWinInt.h" @@ -2551,53 +2551,65 @@ Tcl_WaitPid( } } 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; + /* + * Does the exit code look like one of the exception codes? + */ - 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; + 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 CONTROL_C_EXIT: - *statPtr = SIGINT; - break; + case EXCEPTION_PRIV_INSTRUCTION: + case EXCEPTION_ILLEGAL_INSTRUCTION: + *statPtr = SIGILL; + 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); + case EXCEPTION_ACCESS_VIOLATION: + 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 EXCEPTION_DATATYPE_MISALIGNMENT: + *statPtr = SIGBUS; + break; + + case EXCEPTION_BREAKPOINT: + case EXCEPTION_SINGLE_STEP: + *statPtr = SIGTRAP; + break; + + case CONTROL_C_EXIT: + *statPtr = SIGINT; + break; + + default: + /* + * Non-exceptional, normal, exit code. Note that the + * exit code is truncated to a signed short range + * [-32768,32768) whether it fits into this range or not. + * + * BUG: Even though the exit code is a DWORD, it is + * understood by convention to be a signed integer, yet + * there isn't enough room to fit this into the POSIX + * style waitstatus mask without truncating it. + */ + *statPtr = (((int)(short) exitCode << 8) & 0xffff00); + break; } result = pid; } else { diff --git a/win/tclWinPort.h b/win/tclWinPort.h index 3e6364e..73de9a5 100644 --- a/win/tclWinPort.h +++ b/win/tclWinPort.h @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclWinPort.h,v 1.40 2004/04/06 22:25:58 dgp Exp $ + * RCS: @(#) $Id: tclWinPort.h,v 1.41 2004/05/30 21:57:09 davygrvy Exp $ */ #ifndef _TCLWINPORT @@ -215,6 +215,18 @@ #endif /* !EOVERFLOW */ /* + * Signals not known to the standard ANSI signal.h. These are used + * by Tcl_WaitPid() and generic/tclPosixStr.c + */ + +#ifndef SIGTRAP +# define SIGTRAP 5 +#endif +#ifndef SIGBUS +# define SIGBUS 10 +#endif + +/* * Supply definitions for macros to query wait status, if not already * defined in header files above. */ @@ -230,7 +242,7 @@ #endif #ifndef WEXITSTATUS -# define WEXITSTATUS(stat) (((*((int *) &(stat))) >> 8) & 0xff) +# define WEXITSTATUS(stat) (short)(((*((int *) &(stat))) >> 8) & 0xffff) #endif #ifndef WIFSIGNALED -- cgit v0.12