Release 970804
[wine] / if1632 / signal.c
1 /*
2  * Emulator signal handling
3  *
4  * Copyright 1995 Alexandre Julliard
5  */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <signal.h>
10 #include <string.h>
11 #include <errno.h>
12 #include <time.h>
13 #include <setjmp.h>
14
15 #include <sys/time.h>
16 #include <sys/timeb.h>
17 #include <sys/types.h>
18 #include <sys/wait.h>
19
20 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__svr4__) || defined(_SCO_DS) || defined(__EMX__)
21 # if !defined(_SCO_DS) && !defined(__EMX__)
22 #  include <sys/syscall.h>
23 # endif
24 # include <sys/param.h>
25 #else
26 # include <syscall.h>
27 #endif
28
29 #include "debugger.h"
30 #include "options.h"
31 #include "sigcontext.h"
32 #include "miscemu.h"
33
34
35 /* Signal handler declaration */
36
37 #ifdef linux
38 #define HANDLER_DEF(name) void name (int signal, SIGCONTEXT context_struct)
39 #define HANDLER_PROLOG SIGCONTEXT *context = &context_struct; {
40 #define HANDLER_EPILOG }
41 #elif defined(__svr4__) || defined(_SCO_DS)
42 #define HANDLER_DEF(name) void name (int signal, void *siginfo, SIGCONTEXT *context)
43 #define HANDLER_PROLOG  /* nothing */
44 #define HANDLER_EPILOG  /* nothing */
45 #else
46 #define HANDLER_DEF(name) void name (int signal, int code, SIGCONTEXT *context)
47 #define HANDLER_PROLOG  /* nothing */
48 #define HANDLER_EPILOG  /* nothing */
49 #endif
50
51 extern void SIGNAL_SetHandler( int sig, void (*func)(), int flags );
52 extern BOOL32 INSTR_EmulateInstruction( SIGCONTEXT *context );
53
54
55 /**********************************************************************
56  *              SIGNAL_break
57  * 
58  * Handle Ctrl-C and such
59  */
60 static HANDLER_DEF(SIGNAL_break)
61 {
62     HANDLER_PROLOG;
63     if (Options.debug) wine_debug( signal, context );  /* Enter our debugger */
64     else exit(0);
65     HANDLER_EPILOG;
66 }
67
68
69 /**********************************************************************
70  *              SIGNAL_trap
71  *
72  * SIGTRAP handler.
73  */
74 static HANDLER_DEF(SIGNAL_trap)
75 {
76   HANDLER_PROLOG;
77   wine_debug( signal, context );  /* Enter our debugger */
78   HANDLER_EPILOG;
79 }
80
81
82 /**********************************************************************
83  *              SIGNAL_fault
84  *
85  * Segfault handler.
86  */
87 static HANDLER_DEF(SIGNAL_fault)
88 {
89     HANDLER_PROLOG;
90     if (CS_sig(context) == WINE_CODE_SELECTOR)
91     {
92         fprintf( stderr, "Segmentation fault in Wine program (%04x:%08lx)."
93                          "  Please debug.\n",
94                  (unsigned short) CS_sig(context), EIP_sig(context));
95     }
96     else
97     {
98         if (INSTR_EmulateInstruction( context )) return;
99         fprintf( stderr, "Segmentation fault in Windows program %04x:%08lx.\n",
100                  (unsigned short) CS_sig(context), EIP_sig(context) );
101     }
102     wine_debug( signal, context );
103     HANDLER_EPILOG;
104 }
105
106
107 /**********************************************************************
108  *              SIGNAL_InitEmulator
109  *
110  * Initialize emulator signals.
111  */
112 BOOL32 SIGNAL_InitEmulator(void)
113 {
114     SIGNAL_SetHandler( SIGINT,  (void (*)())SIGNAL_break, 1);
115     SIGNAL_SetHandler( SIGSEGV, (void (*)())SIGNAL_fault, 1);
116     SIGNAL_SetHandler( SIGILL,  (void (*)())SIGNAL_fault, 1);
117     SIGNAL_SetHandler( SIGFPE,  (void (*)())SIGNAL_fault, 1);
118     SIGNAL_SetHandler( SIGTRAP, (void (*)())SIGNAL_trap,  1); /* debugger */
119     SIGNAL_SetHandler( SIGHUP,  (void (*)())SIGNAL_trap,  1); /* forced break*/
120 #ifdef SIGBUS
121     SIGNAL_SetHandler( SIGBUS,  (void (*)())SIGNAL_fault, 1);
122 #endif
123     return TRUE;
124 }