[CRT]
[reactos.git] / reactos / lib / sdk / crt / except / xcptfil.c
1 #include <precomp.h>
2 #include "internal/wine/msvcrt.h"
3 #include "internal/wine/cppexcept.h"
4
5 typedef void (*sighandler_t)(int);
6 static sighandler_t sighandlers[NSIG] = { SIG_DFL };
7
8 /* The exception codes are actually NTSTATUS values */
9 static const struct
10 {
11 NTSTATUS status;
12 int signal;
13 } float_exception_map[] = {
14 { EXCEPTION_FLT_DENORMAL_OPERAND, _FPE_DENORMAL },
15 { EXCEPTION_FLT_DIVIDE_BY_ZERO, _FPE_ZERODIVIDE },
16 { EXCEPTION_FLT_INEXACT_RESULT, _FPE_INEXACT },
17 { EXCEPTION_FLT_INVALID_OPERATION, _FPE_INVALID },
18 { EXCEPTION_FLT_OVERFLOW, _FPE_OVERFLOW },
19 { EXCEPTION_FLT_STACK_CHECK, _FPE_STACKOVERFLOW },
20 { EXCEPTION_FLT_UNDERFLOW, _FPE_UNDERFLOW },
21 };
22
23 /*
24 * @implemented
25 */
26 int CDECL
27 _XcptFilter(NTSTATUS ExceptionCode,
28 struct _EXCEPTION_POINTERS * except)
29 {
30 LONG ret = EXCEPTION_CONTINUE_SEARCH;
31 sighandler_t handler;
32
33 if (!except || !except->ExceptionRecord)
34 return EXCEPTION_CONTINUE_SEARCH;
35
36 switch (except->ExceptionRecord->ExceptionCode)
37 {
38 case EXCEPTION_ACCESS_VIOLATION:
39 if ((handler = sighandlers[SIGSEGV]) != SIG_DFL)
40 {
41 if (handler != SIG_IGN)
42 {
43 sighandlers[SIGSEGV] = SIG_DFL;
44 handler(SIGSEGV);
45 }
46 ret = EXCEPTION_CONTINUE_EXECUTION;
47 }
48 break;
49 /* According to msdn,
50 * the FPE signal handler takes as a second argument the type of
51 * floating point exception.
52 */
53 case EXCEPTION_FLT_DENORMAL_OPERAND:
54 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
55 case EXCEPTION_FLT_INEXACT_RESULT:
56 case EXCEPTION_FLT_INVALID_OPERATION:
57 case EXCEPTION_FLT_OVERFLOW:
58 case EXCEPTION_FLT_STACK_CHECK:
59 case EXCEPTION_FLT_UNDERFLOW:
60 if ((handler = sighandlers[SIGFPE]) != SIG_DFL)
61 {
62 if (handler != SIG_IGN)
63 {
64 unsigned int i;
65 int float_signal = _FPE_INVALID;
66
67 sighandlers[SIGFPE] = SIG_DFL;
68 for (i = 0; i < sizeof(float_exception_map) /
69 sizeof(float_exception_map[0]); i++)
70 {
71 if (float_exception_map[i].status ==
72 except->ExceptionRecord->ExceptionCode)
73 {
74 float_signal = float_exception_map[i].signal;
75 break;
76 }
77 }
78 ((float_handler)handler)(SIGFPE, float_signal);
79 }
80 ret = EXCEPTION_CONTINUE_EXECUTION;
81 }
82 break;
83 case EXCEPTION_ILLEGAL_INSTRUCTION:
84 case EXCEPTION_PRIV_INSTRUCTION:
85 if ((handler = sighandlers[SIGILL]) != SIG_DFL)
86 {
87 if (handler != SIG_IGN)
88 {
89 sighandlers[SIGILL] = SIG_DFL;
90 handler(SIGILL);
91 }
92 ret = EXCEPTION_CONTINUE_EXECUTION;
93 }
94 break;
95 }
96 return ret;
97 }
98