summaryrefslogtreecommitdiffstats
path: root/win
diff options
context:
space:
mode:
authordavygrvy <davygrvy@pobox.com>2004-05-30 21:57:09 (GMT)
committerdavygrvy <davygrvy@pobox.com>2004-05-30 21:57:09 (GMT)
commit0c988adc2fbfe2e8803d169aaf90abccf11842a7 (patch)
treea2df1f8140446d183449bc1cb1eee15f19cce927 /win
parent6c850f4e8fd30d0c0826b5e9af5b627b36bff7b2 (diff)
downloadtcl-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.c100
-rw-r--r--win/tclWinPort.h16
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