11 #include <sys/timeb.h>
12 #include <sys/types.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>
19 #include <sys/param.h>
26 #include "sigcontext.h"
30 #if !defined(BSD4_4) || defined(linux) || defined(__FreeBSD__)
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
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
));
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 */
73 #define HANDLER_DEF(name) void name (int signal, int code, SIGCONTEXT *context)
74 #define HANDLER_PROLOG /* nothing */
75 #define HANDLER_EPILOG /* nothing */
78 extern BOOL32
INSTR_EmulateInstruction( SIGCONTEXT
*context
);
80 /**********************************************************************
86 HANDLER_DEF(wine_timer
)
89 /* Should do real-time timers here */
94 /**********************************************************************
97 * Handle Ctrl-C and such
100 HANDLER_DEF(SIGNAL_break
)
103 if (Options
.debug
) wine_debug( signal
, context
); /* Enter our debugger */
108 /**********************************************************************
111 * wait4 terminated child processes
114 HANDLER_DEF(SIGNAL_child
)
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
);
129 /**********************************************************************
135 HANDLER_DEF(SIGNAL_trap
)
138 wine_debug( signal
, context
); /* Enter our debugger */
143 /**********************************************************************
149 HANDLER_DEF(SIGNAL_fault
)
152 if (CS_sig(context
) == WINE_CODE_SELECTOR
)
154 fprintf( stderr
, "Segmentation fault in Wine program (%04x:%08lx)."
156 (unsigned short) CS_sig(context
), EIP_sig(context
));
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
);
169 /**********************************************************************
172 static void SIGNAL_SetHandler( int sig
, void (*func
)(), int flags
)
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
182 sig_act
.sa_restorer
=
183 (void (*)()) (((unsigned int)(cstack
) + sizeof(cstack
) - 4) & ~3);
184 ret
= wine_sigaction( sig
, &sig_act
, NULL
);
187 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
188 struct sigaction sig_act
;
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
;
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 */
208 struct sigaction sig_act
;
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
);
219 perror( "sigaction" );
224 extern void stop_wait(int a
);
225 extern void WINSOCK_sigio(int a
);
228 /**********************************************************************
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",
241 ss
.ss_size
= MINSIGSTKSZ
;
243 if (sigaltstack(&ss
, NULL
) < 0) {
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",
257 ss
.ss_size
= SIGSTKSZ
;
259 if (sigaltstack(&ss
, NULL
) < 0) {
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 */
274 SIGNAL_SetHandler( SIGBUS
, (void (*)())SIGNAL_fault
, 1);
277 SIGNAL_SetHandler( SIGUSR2
, (void (*)())stop_wait
, 1); /* For IPC */
279 #ifndef __EMX__ /* FIXME */
280 SIGNAL_SetHandler( SIGIO
, (void (*)())WINSOCK_sigio
, 0);
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;
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
);
307 /**********************************************************************
308 * SIGNAL_MaskAsyncEvents
310 void SIGNAL_MaskAsyncEvents( BOOL32 flag
)
314 #ifndef __EMX__ /* FIXME */
315 sigaddset(&set
, SIGIO
);
317 sigaddset(&set
, SIGUSR1
);
319 sigaddset(&set
, SIGUSR2
);
321 sigprocmask( (flag
) ? SIG_BLOCK
: SIG_UNBLOCK
, &set
, NULL
);
324 #endif /* ifndef WINELIB */