Release 970215
[wine/multimedia.git] / loader / signal.c
blobe1fba1f4d54fb86d1ce381a8616de366a7956560
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>
12 #include <sys/types.h>
13 #include <sys/wait.h>
15 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__svr4__) || defined(_SCO_DS) || defined(__EMX__)
16 #if !defined(_SCO_DS) && !defined(__EMX__)
17 #include <sys/syscall.h>
18 #endif
19 #include <sys/param.h>
20 #else
21 #include <syscall.h>
22 #endif
24 #include "debugger.h"
25 #include "options.h"
26 #include "sigcontext.h"
27 #include "win.h"
28 #include "winsock.h"
30 #if !defined(BSD4_4) || defined(linux) || defined(__FreeBSD__)
31 char * cstack[4096];
32 #endif
34 #ifdef linux
35 extern void ___sig_restore();
36 extern void ___masksig_restore();
38 /* Similar to the sigaction function in libc, except it leaves alone the
39 restorer field */
41 static int
42 wine_sigaction(int sig,struct sigaction * new, struct sigaction * old)
44 __asm__("int $0x80":"=a" (sig)
45 :"0" (SYS_sigaction),"b" (sig),"c" (new),"d" (old));
46 if (sig>=0)
47 return 0;
48 errno = -sig;
49 return -1;
51 #endif
53 extern BOOL32 INSTR_EmulateInstruction( SIGCONTEXT *context );
55 /**********************************************************************
56 * wine_timer
58 * SIGALRM handler.
60 #ifdef linux
61 static void wine_timer(int signal, SIGCONTEXT context_struct)
63 #elif defined(__svr4__)
64 static void wine_timer(int signal, void *siginfo, SIGCONTEXT *context)
66 #else
67 static void wine_timer(int signal, int code, SIGCONTEXT *context)
69 #endif
70 /* Should do real-time timers here */
72 DOSMEM_Tick();
75 /**********************************************************************
76 * SIGNAL_break
78 * Handle Ctrl-C and such
80 #ifdef linux
81 static void SIGNAL_break(int signal, SIGCONTEXT context_struct)
83 SIGCONTEXT *context = &context_struct;
84 #elif defined(__svr4__) || defined(_SCO_DS)
85 static void SIGNAL_break(int signal, void *siginfo, SIGCONTEXT *context)
87 #else
88 static void SIGNAL_break(int signal, int code, SIGCONTEXT *context)
90 #endif
91 if (Options.debug) wine_debug( signal, context ); /* Enter our debugger */
92 exit(0);
95 /**********************************************************************
96 * SIGNAL_child
98 * wait4 terminated child processes
100 static void SIGNAL_child(void)
102 #if defined(__svr4__) || defined(__EMX__)
103 wait(NULL);
104 #else
105 wait4( 0, NULL, WNOHANG, NULL);
106 #endif
110 /**********************************************************************
111 * SIGNAL_trap
113 * SIGTRAP handler.
115 #ifdef linux
116 static void SIGNAL_trap(int signal, SIGCONTEXT context_struct)
118 SIGCONTEXT *context = &context_struct;
119 #elif defined(__svr4__) || defined(_SCO_DS)
120 static void SIGNAL_trap(int signal, void *siginfo, SIGCONTEXT *context)
122 #else
123 static void SIGNAL_trap(int signal, int code, SIGCONTEXT *context)
125 #endif
126 wine_debug( signal, context ); /* Enter our debugger */
130 /**********************************************************************
131 * SIGNAL_fault
133 * Segfault handler.
135 #ifdef linux
136 static void SIGNAL_fault(int signal, SIGCONTEXT context_struct)
138 SIGCONTEXT *context = &context_struct;
139 #elif defined(__svr4__) || defined(_SCO_DS)
140 static void SIGNAL_fault(int signal, void *siginfo, SIGCONTEXT *context)
142 #else
143 static void SIGNAL_fault(int signal, int code, SIGCONTEXT *context)
145 #endif
146 if (CS_sig(context) == WINE_CODE_SELECTOR)
148 fprintf( stderr, "Segmentation fault in Wine program (%x:%lx)."
149 " Please debug.\n",
150 CS_sig(context), EIP_sig(context) );
152 else
154 if (INSTR_EmulateInstruction( context )) return;
155 fprintf( stderr, "Segmentation fault in Windows program %x:%lx.\n",
156 CS_sig(context), EIP_sig(context) );
158 wine_debug( signal, context );
162 /**********************************************************************
163 * SIGNAL_SetHandler
165 static void SIGNAL_SetHandler( int sig, void (*func)(), int flags )
167 int ret;
168 struct sigaction sig_act;
170 #ifdef linux
171 sig_act.sa_handler = func;
172 sig_act.sa_flags = SA_RESTART | (flags) ? SA_NOMASK : 0;
173 /* Point to the top of the stack, minus 4 just in case, and make
174 it aligned */
175 sig_act.sa_restorer =
176 (void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
177 ret = wine_sigaction( sig, &sig_act, NULL );
178 #endif /* linux */
180 #if defined(__NetBSD__) || defined(__FreeBSD__)
181 sigset_t sig_mask;
182 sigemptyset(&sig_mask);
183 sig_act.sa_handler = func;
184 sig_act.sa_flags = SA_ONSTACK;
185 sig_act.sa_mask = sig_mask;
186 ret = sigaction( sig, &sig_act, NULL );
187 #endif /* __FreeBSD__ || __NetBSD__ */
189 #if defined (__svr4__) || defined(_SCO_DS)
190 sigset_t sig_mask;
191 sigemptyset(&sig_mask);
192 sig_act.sa_handler = func;
193 sig_act.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_RESTART;
194 sig_act.sa_mask = sig_mask;
195 ret = sigaction( sig, &sig_act, NULL );
196 #endif /* __svr4__ || _SCO_DS */
198 #if defined(__EMX__)
199 sigset_t sig_mask;
200 sigemptyset(&sig_mask);
201 sig_act.sa_handler = func;
202 sig_act.sa_flags = 0; /* FIXME: EMX has only SA_ACK and SA_SYSV */
203 sig_act.sa_mask = sig_mask;
204 ret = sigaction( sig, &sig_act, NULL );
205 #endif /* __EMX__ */
207 if (ret < 0)
209 perror( "sigaction" );
210 exit(1);
214 extern void stop_wait(int a);
215 extern void WINSOCK_sigio(int a);
218 /**********************************************************************
219 * SIGNAL_Init
221 BOOL32 SIGNAL_Init(void)
223 #if defined(__NetBSD__) || defined(__FreeBSD__)
224 struct sigaltstack ss;
226 if ((ss.ss_sp = malloc(MINSIGSTKSZ)) == NULL) {
227 fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
228 MINSIGSTKSZ);
229 return FALSE;
231 ss.ss_size = MINSIGSTKSZ;
232 ss.ss_flags = 0;
233 if (sigaltstack(&ss, NULL) < 0) {
234 perror("sigstack");
235 return FALSE;
237 #endif /* __FreeBSD__ || __NetBSD__ */
239 #if defined (__svr4__) || defined(_SCO_DS)
240 struct sigaltstack ss;
242 if ((ss.ss_sp = malloc(SIGSTKSZ) ) == NULL) {
243 fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
244 SIGSTKSZ);
245 return FALSE;
247 ss.ss_size = SIGSTKSZ;
248 ss.ss_flags = 0;
249 if (sigaltstack(&ss, NULL) < 0) {
250 perror("sigstack");
251 return FALSE;
253 #endif /* __svr4__ || _SCO_DS */
255 SIGNAL_SetHandler( SIGALRM, (void (*)())wine_timer, 1);
256 SIGNAL_SetHandler( SIGINT, (void (*)())SIGNAL_break, 1);
257 SIGNAL_SetHandler( SIGCHLD, (void (*)())SIGNAL_child, 1);
258 SIGNAL_SetHandler( SIGSEGV, (void (*)())SIGNAL_fault, 1);
259 SIGNAL_SetHandler( SIGILL, (void (*)())SIGNAL_fault, 1);
260 SIGNAL_SetHandler( SIGFPE, (void (*)())SIGNAL_fault, 1);
261 SIGNAL_SetHandler( SIGTRAP, (void (*)())SIGNAL_trap, 1); /* debugger */
262 SIGNAL_SetHandler( SIGHUP, (void (*)())SIGNAL_trap, 1); /* forced break */
263 #ifdef SIGBUS
264 SIGNAL_SetHandler( SIGBUS, (void (*)())SIGNAL_fault, 1);
265 #endif
266 #ifdef CONFIG_IPC
267 SIGNAL_SetHandler( SIGUSR2, (void (*)())stop_wait, 1); /* For IPC */
268 #endif
269 #ifndef __EMX__ /* FIXME */
270 SIGNAL_SetHandler( SIGIO, (void (*)())WINSOCK_sigio, 0);
271 #endif
272 return TRUE;
276 /**********************************************************************
277 * SIGNAL_StartBIOSTimer
279 * Start the BIOS tick timer.
281 void SIGNAL_StartBIOSTimer(void)
283 #ifndef __EMX__ /* FIXME: Time don't work... Use BIOS directly instead */
284 struct itimerval vt_timer;
285 static int timer_started = 0;
287 if (timer_started) return;
288 timer_started = 1;
289 vt_timer.it_interval.tv_sec = 0;
290 vt_timer.it_interval.tv_usec = 54929;
291 vt_timer.it_value = vt_timer.it_interval;
293 setitimer(ITIMER_REAL, &vt_timer, NULL);
294 #endif
297 /**********************************************************************
298 * SIGNAL_MaskAsyncEvents
300 void SIGNAL_MaskAsyncEvents( BOOL32 flag )
302 sigset_t set;
303 sigemptyset(&set);
304 #ifndef __EMX__ /* FIXME */
305 sigaddset(&set, SIGIO);
306 #endif
307 sigaddset(&set, SIGUSR1);
308 #ifdef CONFIG_IPC
309 sigaddset(&set, SIGUSR2);
310 #endif
311 sigprocmask( (flag) ? SIG_BLOCK : SIG_UNBLOCK , &set, NULL);
314 #endif /* ifndef WINELIB */