diff options
author | davygrvy <davygrvy@pobox.com> | 2004-05-30 21:57:09 (GMT) |
---|---|---|
committer | davygrvy <davygrvy@pobox.com> | 2004-05-30 21:57:09 (GMT) |
commit | 0c988adc2fbfe2e8803d169aaf90abccf11842a7 (patch) | |
tree | a2df1f8140446d183449bc1cb1eee15f19cce927 /win | |
parent | 6c850f4e8fd30d0c0826b5e9af5b627b36bff7b2 (diff) | |
download | tcl-0c988adc2fbfe2e8803d169aaf90abccf11842a7.zip tcl-0c988adc2fbfe2e8803d169aaf90abccf11842a7.tar.gz tcl-0c988adc2fbfe2e8803d169aaf90abccf11842a7.tar.bz2 |
* 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.
Diffstat (limited to 'win')
-rw-r--r-- | win/tclWinPipe.c | 100 | ||||
-rw-r--r-- | 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 |