FreeBASIC  0.91.0
signals.c
Go to the documentation of this file.
1 /* signal handlers */
2 
3 #include "fb.h"
4 #include <signal.h>
5 
6 #if defined( HOST_WIN32 )
7 #include <windows.h>
8 
9 static LPTOP_LEVEL_EXCEPTION_FILTER old_excpfilter;
10 
11 /* low-level signal handler for Windows */
12 static __stdcall LONG exception_filter( LPEXCEPTION_POINTERS info )
13 {
14 
15  switch( info->ExceptionRecord->ExceptionCode )
16  {
17  case EXCEPTION_ACCESS_VIOLATION:
18  case EXCEPTION_STACK_OVERFLOW:
19  raise( SIGSEGV );
20  break;
21 
22  case EXCEPTION_FLT_DIVIDE_BY_ZERO:
23  case EXCEPTION_FLT_OVERFLOW:
24  case EXCEPTION_INT_DIVIDE_BY_ZERO:
25  case EXCEPTION_INT_OVERFLOW:
26  raise( SIGFPE );
27  break;
28  }
29 
30  return old_excpfilter( info );
31 }
32 #endif
33 
34 typedef struct _FB_SIGHANDLER {
35  int errnum;
36  void (*oldhnd)(int);
38 
39 static FB_SIGHANDLER sigTb[NSIG];
40 
41 #define FB_SETUPSIGNAL(n,h) \
42  sigTb[n].oldhnd = signal( n, h ); \
43  sigTb[n].errnum = FB_RTERROR_##n;
44 
45 static void gen_handler( int sig )
46 {
47  FB_ERRHANDLER handler;
48 
49  /* don't cause another exception */
50  if( (sig < 0) || (sig >= NSIG) || (sigTb[sig].errnum == FB_RTERROR_OK) )
51  {
52  raise( sig );
53  return;
54  }
55 
56  /* call user handler if any defined */
57  handler = fb_ErrorThrowEx( sigTb[sig].errnum, -1, NULL, NULL, NULL );
58  if( handler != NULL )
59  handler( );
60 
61  /* if the user handler returned, exit */
62  fb_End( sigTb[sig].errnum );
63 }
64 
65 FBCALL void fb_InitSignals( void )
66 {
67  memset( sigTb, 0, sizeof(sigTb) );
68 
69  FB_SETUPSIGNAL(SIGABRT, gen_handler)
72  FB_SETUPSIGNAL(SIGSEGV, gen_handler)
73  FB_SETUPSIGNAL(SIGTERM, gen_handler)
75 #ifdef SIGQUIT
76  FB_SETUPSIGNAL(SIGQUIT, gen_handler)
77 #endif
78 
79 #if defined( HOST_WIN32 )
80  old_excpfilter = SetUnhandledExceptionFilter( exception_filter );
81 #endif
82 }