Release 960611
[wine/multimedia.git] / loader / signal.c
blob0d200ca766e56513e1040295ee43893c1c206236
1 #ifndef WINELIB
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <signal.h>
5 #include <string.h>
6 #include <errno.h>
7 #include <time.h>
8 #include <setjmp.h>
10 #include <sys/time.h>
11 #include <sys/timeb.h>
13 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__svr4__) || defined(_SCO_DS)
14 #ifndef _SCO_DS
15 #include <sys/syscall.h>
16 #endif
17 #include <sys/param.h>
18 #else
19 #include <syscall.h>
20 #endif
22 #include "debugger.h"
23 #include "miscemu.h"
24 #include "registers.h"
25 #include "win.h"
27 #if !defined(BSD4_4) || defined(linux) || defined(__FreeBSD__)
28 char * cstack[4096];
29 #endif
31 #ifdef linux
32 extern void ___sig_restore();
33 extern void ___masksig_restore();
35 /* Similar to the sigaction function in libc, except it leaves alone the
36 restorer field */
38 static int
39 wine_sigaction(int sig,struct sigaction * new, struct sigaction * old)
41 __asm__("int $0x80":"=a" (sig)
42 :"0" (SYS_sigaction),"b" (sig),"c" (new),"d" (old));
43 if (sig>=0)
44 return 0;
45 errno = -sig;
46 return -1;
48 #endif
51 /**********************************************************************
52 * wine_timer
54 * SIGALRM handler.
56 #ifdef linux
57 static void wine_timer(int signal, struct sigcontext_struct context_struct)
59 #elif defined(__svr4__)
60 static void wine_timer(int signal, void *siginfo, ucontext_t *context)
62 #else
63 static void wine_timer(int signal, int code, struct sigcontext *context)
65 #endif
66 /* Should do real-time timers here */
68 DOSMEM_Tick();
72 /**********************************************************************
73 * SIGNAL_trap
75 * SIGTRAP handler.
77 #ifdef linux
78 static void SIGNAL_trap(int signal, struct sigcontext_struct context_struct)
80 struct sigcontext_struct *context = &context_struct;
81 #elif defined(__svr4__) || defined(_SCO_DS)
82 static void SIGNAL_trap(int signal, void *siginfo, ucontext_t *context)
84 #else
85 static void SIGNAL_trap(int signal, int code, struct sigcontext *context)
87 #endif
88 wine_debug( signal, context ); /* Enter our debugger */
92 /**********************************************************************
93 * SIGNAL_fault
95 * Segfault handler.
97 #ifdef linux
98 static void SIGNAL_fault(int signal, struct sigcontext_struct context_struct)
100 struct sigcontext_struct *context = &context_struct;
101 #elif defined(__svr4__) || defined(_SCO_DS)
102 static void SIGNAL_fault(int signal, void *siginfo, ucontext_t *context)
104 #else
105 static void SIGNAL_fault(int signal, int code, struct sigcontext *context)
107 #endif
108 if (CS_reg(context) == WINE_CODE_SELECTOR)
110 fprintf( stderr, "Segmentation fault in Wine program (%x:%lx)."
111 " Please debug.\n",
112 CS_reg(context), EIP_reg(context) );
114 else
116 if (INSTR_EmulateInstruction( context )) return;
117 fprintf( stderr, "Segmentation fault in Windows program %x:%lx.\n",
118 CS_reg(context), EIP_reg(context) );
120 wine_debug( signal, context );
124 /**********************************************************************
125 * SIGNAL_SetHandler
127 static void SIGNAL_SetHandler( int sig, void (*func)() )
129 int ret;
130 struct sigaction sig_act;
132 #ifdef linux
133 sig_act.sa_handler = func;
134 sig_act.sa_flags = SA_RESTART | SA_NOMASK;
135 /* Point to the top of the stack, minus 4 just in case, and make
136 it aligned */
137 sig_act.sa_restorer =
138 (void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
139 ret = wine_sigaction( sig, &sig_act, NULL );
140 #endif /* linux */
142 #if defined(__NetBSD__) || defined(__FreeBSD__)
143 sigset_t sig_mask;
144 sigemptyset(&sig_mask);
145 sig_act.sa_handler = func;
146 sig_act.sa_flags = SA_ONSTACK;
147 sig_act.sa_mask = sig_mask;
148 ret = sigaction( sig, &sig_act, NULL );
149 #endif /* __FreeBSD__ || __NetBSD__ */
151 #if defined (__svr4__) || defined(_SCO_DS)
152 sigset_t sig_mask;
153 sigemptyset(&sig_mask);
154 sig_act.sa_handler = func;
155 sig_act.sa_flags = SA_ONSTACK | SA_SIGINFO;
156 sig_act.sa_mask = sig_mask;
157 ret = sigaction( sig, &sig_act, NULL );
158 #endif /* __svr4__ || _SCO_DS */
160 if (ret < 0)
162 perror( "sigaction" );
163 exit(1);
167 extern void stop_wait(int a);
170 /**********************************************************************
171 * init_wine_signals
173 void init_wine_signals(void)
175 #if defined(__NetBSD__) || defined(__FreeBSD__)
176 struct sigaltstack ss;
178 if ((ss.ss_sp = malloc(MINSIGSTKSZ)) == NULL) {
179 fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
180 MINSIGSTKSZ);
181 exit(1);
183 ss.ss_size = MINSIGSTKSZ;
184 ss.ss_flags = 0;
185 if (sigaltstack(&ss, NULL) < 0) {
186 perror("sigstack");
187 exit(1);
189 #endif /* __FreeBSD__ || __NetBSD__ */
191 #if defined (__svr4__) || defined(_SCO_DS)
192 struct sigaltstack ss;
194 if ((ss.ss_sp = malloc(SIGSTKSZ) ) == NULL) {
195 fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
196 SIGSTKSZ);
197 exit(1);
199 ss.ss_size = SIGSTKSZ;
200 ss.ss_flags = 0;
201 if (sigaltstack(&ss, NULL) < 0) {
202 perror("sigstack");
203 exit(1);
205 #endif /* __svr4__ || _SCO_DS */
207 SIGNAL_SetHandler( SIGALRM, (void (*)())wine_timer );
208 SIGNAL_SetHandler( SIGSEGV, (void (*)())SIGNAL_fault );
209 SIGNAL_SetHandler( SIGILL, (void (*)())SIGNAL_fault );
210 SIGNAL_SetHandler( SIGFPE, (void (*)())SIGNAL_fault );
211 SIGNAL_SetHandler( SIGTRAP, (void (*)())SIGNAL_trap ); /* debugger */
212 SIGNAL_SetHandler( SIGHUP, (void (*)())SIGNAL_trap ); /* forced break */
213 #ifdef SIGBUS
214 SIGNAL_SetHandler( SIGBUS, (void (*)())SIGNAL_fault );
215 #endif
216 #ifdef CONFIG_IPC
217 SIGNAL_SetHandler( SIGUSR2, (void (*)())stop_wait ); /* For IPC */
218 #endif
222 /**********************************************************************
223 * SIGNAL_StartBIOSTimer
225 * Start the BIOS tick timer.
227 void SIGNAL_StartBIOSTimer(void)
229 struct itimerval vt_timer;
230 static int timer_started = 0;
232 if (timer_started) return;
233 timer_started = 1;
234 vt_timer.it_interval.tv_sec = 0;
235 vt_timer.it_interval.tv_usec = 54929;
236 vt_timer.it_value = vt_timer.it_interval;
238 setitimer(ITIMER_REAL, &vt_timer, NULL);
241 #endif /* ifndef WINELIB */