Release 970720
[wine/multimedia.git] / loader / signal.c
blob43aae82086a15897bab568d1d6703a09cbfaff2c
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(__OpenBSD__) || 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 /* This is the sigaction structure from the Linux 2.1.20 kernel. */
40 struct kernel_sigaction {
41 __sighandler_t sa_handler;
42 unsigned long sa_mask;
43 unsigned long sa_flags;
44 void (*sa_restorer) __P ((void));
47 /* Similar to the sigaction function in libc, except it leaves alone the
48 restorer field */
50 static int
51 wine_sigaction(int sig,struct kernel_sigaction * new,
52 struct kernel_sigaction * old)
54 __asm__("int $0x80":"=a" (sig)
55 :"0" (SYS_sigaction),"b" (sig),"c" (new),"d" (old));
56 if (sig>=0)
57 return 0;
58 errno = -sig;
59 return -1;
61 #endif /* linux */
64 #ifdef linux
65 #define HANDLER_DEF(name) void name (int signal, SIGCONTEXT context_struct)
66 #define HANDLER_PROLOG SIGCONTEXT *context = &context_struct; (void)context; {
67 #define HANDLER_EPILOG }
68 #elif defined(__svr4__) || defined(_SCO_DS)
69 #define HANDLER_DEF(name) void name (int signal, void *siginfo, SIGCONTEXT *context)
70 #define HANDLER_PROLOG /* nothing */
71 #define HANDLER_EPILOG /* nothing */
72 #else
73 #define HANDLER_DEF(name) void name (int signal, int code, SIGCONTEXT *context)
74 #define HANDLER_PROLOG /* nothing */
75 #define HANDLER_EPILOG /* nothing */
76 #endif
78 extern BOOL32 INSTR_EmulateInstruction( SIGCONTEXT *context );
80 /**********************************************************************
81 * wine_timer
83 * SIGALRM handler.
85 static
86 HANDLER_DEF(wine_timer)
88 HANDLER_PROLOG;
89 /* Should do real-time timers here */
90 DOSMEM_Tick();
91 HANDLER_EPILOG;
94 /**********************************************************************
95 * SIGNAL_break
97 * Handle Ctrl-C and such
99 static
100 HANDLER_DEF(SIGNAL_break)
102 HANDLER_PROLOG;
103 if (Options.debug) wine_debug( signal, context ); /* Enter our debugger */
104 exit(0);
105 HANDLER_EPILOG;
108 /**********************************************************************
109 * SIGNAL_child
111 * wait4 terminated child processes
113 static
114 HANDLER_DEF(SIGNAL_child)
116 HANDLER_PROLOG;
117 #ifdef HAVE_WAIT4
118 wait4( 0, NULL, WNOHANG, NULL);
119 #elif defined (HAVE_WAITPID)
120 /* I am sort-of guessing that this is the same as the wait4 call. */
121 waitpid (0, NULL, WNOHANG);
122 #else
123 wait(NULL);
124 #endif
125 HANDLER_EPILOG;
129 /**********************************************************************
130 * SIGNAL_trap
132 * SIGTRAP handler.
134 static
135 HANDLER_DEF(SIGNAL_trap)
137 HANDLER_PROLOG;
138 wine_debug( signal, context ); /* Enter our debugger */
139 HANDLER_EPILOG;
143 /**********************************************************************
144 * SIGNAL_fault
146 * Segfault handler.
148 static
149 HANDLER_DEF(SIGNAL_fault)
151 HANDLER_PROLOG;
152 if (CS_sig(context) == WINE_CODE_SELECTOR)
154 fprintf( stderr, "Segmentation fault in Wine program (%04x:%08lx)."
155 " Please debug.\n",
156 (unsigned short) CS_sig(context), EIP_sig(context));
158 else
160 if (INSTR_EmulateInstruction( context )) return;
161 fprintf( stderr, "Segmentation fault in Windows program %04x:%08lx.\n",
162 (unsigned short) CS_sig(context), EIP_sig(context) );
164 wine_debug( signal, context );
165 HANDLER_EPILOG;
169 /**********************************************************************
170 * SIGNAL_SetHandler
172 static void SIGNAL_SetHandler( int sig, void (*func)(), int flags )
174 int ret;
176 #ifdef linux
177 struct kernel_sigaction sig_act;
178 sig_act.sa_handler = func;
179 sig_act.sa_flags = SA_RESTART | (flags) ? SA_NOMASK : 0;
180 /* Point to the top of the stack, minus 4 just in case, and make
181 it aligned */
182 sig_act.sa_restorer =
183 (void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
184 ret = wine_sigaction( sig, &sig_act, NULL );
185 #endif /* linux */
187 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
188 struct sigaction sig_act;
189 sigset_t sig_mask;
190 sigemptyset(&sig_mask);
191 sig_act.sa_handler = func;
192 sig_act.sa_flags = SA_ONSTACK;
193 sig_act.sa_mask = sig_mask;
194 ret = sigaction( sig, &sig_act, NULL );
195 #endif /* __FreeBSD__ || __NetBSD__ || __OpenBSD__ */
197 #if defined (__svr4__) || defined(_SCO_DS)
198 struct sigaction sig_act;
199 sigset_t sig_mask;
200 sigemptyset(&sig_mask);
201 sig_act.sa_handler = func;
202 sig_act.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_RESTART;
203 sig_act.sa_mask = sig_mask;
204 ret = sigaction( sig, &sig_act, NULL );
205 #endif /* __svr4__ || _SCO_DS */
207 #if defined(__EMX__)
208 struct sigaction sig_act;
209 sigset_t sig_mask;
210 sigemptyset(&sig_mask);
211 sig_act.sa_handler = func;
212 sig_act.sa_flags = 0; /* FIXME: EMX has only SA_ACK and SA_SYSV */
213 sig_act.sa_mask = sig_mask;
214 ret = sigaction( sig, &sig_act, NULL );
215 #endif /* __EMX__ */
217 if (ret < 0)
219 perror( "sigaction" );
220 exit(1);
224 extern void stop_wait(int a);
225 extern void WINSOCK_sigio(int a);
228 /**********************************************************************
229 * SIGNAL_Init
231 BOOL32 SIGNAL_Init(void)
233 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
234 struct sigaltstack ss;
236 if ((ss.ss_sp = malloc(MINSIGSTKSZ)) == NULL) {
237 fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
238 MINSIGSTKSZ);
239 return FALSE;
241 ss.ss_size = MINSIGSTKSZ;
242 ss.ss_flags = 0;
243 if (sigaltstack(&ss, NULL) < 0) {
244 perror("sigstack");
245 return FALSE;
247 #endif /* __FreeBSD__ || __NetBSD__ || __OpenBSD__ */
249 #if defined (__svr4__) || defined(_SCO_DS)
250 struct sigaltstack ss;
252 if ((ss.ss_sp = malloc(SIGSTKSZ) ) == NULL) {
253 fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
254 SIGSTKSZ);
255 return FALSE;
257 ss.ss_size = SIGSTKSZ;
258 ss.ss_flags = 0;
259 if (sigaltstack(&ss, NULL) < 0) {
260 perror("sigstack");
261 return FALSE;
263 #endif /* __svr4__ || _SCO_DS */
265 SIGNAL_SetHandler( SIGALRM, (void (*)())wine_timer, 1);
266 SIGNAL_SetHandler( SIGINT, (void (*)())SIGNAL_break, 1);
267 SIGNAL_SetHandler( SIGCHLD, (void (*)())SIGNAL_child, 1);
268 SIGNAL_SetHandler( SIGSEGV, (void (*)())SIGNAL_fault, 1);
269 SIGNAL_SetHandler( SIGILL, (void (*)())SIGNAL_fault, 1);
270 SIGNAL_SetHandler( SIGFPE, (void (*)())SIGNAL_fault, 1);
271 SIGNAL_SetHandler( SIGTRAP, (void (*)())SIGNAL_trap, 1); /* debugger */
272 SIGNAL_SetHandler( SIGHUP, (void (*)())SIGNAL_trap, 1); /* forced break */
273 #ifdef SIGBUS
274 SIGNAL_SetHandler( SIGBUS, (void (*)())SIGNAL_fault, 1);
275 #endif
276 #ifdef CONFIG_IPC
277 SIGNAL_SetHandler( SIGUSR2, (void (*)())stop_wait, 1); /* For IPC */
278 #endif
279 #ifndef __EMX__ /* FIXME */
280 SIGNAL_SetHandler( SIGIO, (void (*)())WINSOCK_sigio, 0);
281 #endif
282 return TRUE;
286 /**********************************************************************
287 * SIGNAL_StartBIOSTimer
289 * Start the BIOS tick timer.
291 void SIGNAL_StartBIOSTimer(void)
293 #ifndef __EMX__ /* FIXME: Time don't work... Use BIOS directly instead */
294 struct itimerval vt_timer;
295 static int timer_started = 0;
297 if (timer_started) return;
298 timer_started = 1;
299 vt_timer.it_interval.tv_sec = 0;
300 vt_timer.it_interval.tv_usec = 54929;
301 vt_timer.it_value = vt_timer.it_interval;
303 setitimer(ITIMER_REAL, &vt_timer, NULL);
304 #endif
307 /**********************************************************************
308 * SIGNAL_MaskAsyncEvents
310 void SIGNAL_MaskAsyncEvents( BOOL32 flag )
312 sigset_t set;
313 sigemptyset(&set);
314 #ifndef __EMX__ /* FIXME */
315 sigaddset(&set, SIGIO);
316 #endif
317 sigaddset(&set, SIGUSR1);
318 #ifdef CONFIG_IPC
319 sigaddset(&set, SIGUSR2);
320 #endif
321 sigprocmask( (flag) ? SIG_BLOCK : SIG_UNBLOCK , &set, NULL);
324 #endif /* ifndef WINELIB */