5 #include <linux/signal.h>
15 #include <sys/timeb.h>
16 #include <sys/types.h>
19 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__svr4__) || defined(_SCO_DS) || defined(__EMX__)
20 #if !defined(_SCO_DS) && !defined(__EMX__)
21 #include <sys/syscall.h>
23 #include <sys/param.h>
30 #include "sigcontext.h"
34 #if !defined(BSD4_4) || defined(linux) || defined(__FreeBSD__)
39 extern void ___sig_restore();
40 extern void ___masksig_restore();
42 /* Similar to the sigaction function in libc, except it leaves alone the
46 wine_sigaction(int sig
,struct sigaction
* new, struct sigaction
* old
)
48 __asm__("int $0x80":"=a" (sig
)
49 :"0" (SYS_sigaction
),"b" (sig
),"c" (new),"d" (old
));
59 #define HANDLER_DEF(name) void name (int signal, SIGCONTEXT context_struct)
60 #define HANDLER_PROLOG SIGCONTEXT *context = &context_struct; (void)context; {
61 #define HANDLER_EPILOG }
62 #elif defined(__svr4__) || defined(_SCO_DS)
63 #define HANDLER_DEF(name) void name (int signal, void *siginfo, SIGCONTEXT *context)
64 #define HANDLER_PROLOG /* nothing */
65 #define HANDLER_EPILOG /* nothing */
67 #define HANDLER_DEF(name) void name (int signal, int code, SIGCONTEXT *context)
68 #define HANDLER_PROLOG /* nothing */
69 #define HANDLER_EPILOG /* nothing */
72 extern BOOL32
INSTR_EmulateInstruction( SIGCONTEXT
*context
);
74 /**********************************************************************
80 HANDLER_DEF(wine_timer
)
83 /* Should do real-time timers here */
88 /**********************************************************************
91 * Handle Ctrl-C and such
94 HANDLER_DEF(SIGNAL_break
)
97 if (Options
.debug
) wine_debug( signal
, context
); /* Enter our debugger */
102 /**********************************************************************
105 * wait4 terminated child processes
108 HANDLER_DEF(SIGNAL_child
)
112 wait4( 0, NULL
, WNOHANG
, NULL
);
113 #elif defined (HAVE_WAITPID)
114 /* I am sort-of guessing that this is the same as the wait4 call. */
115 waitpid (0, NULL
, WNOHANG
);
123 /**********************************************************************
129 HANDLER_DEF(SIGNAL_trap
)
132 wine_debug( signal
, context
); /* Enter our debugger */
137 /**********************************************************************
143 HANDLER_DEF(SIGNAL_fault
)
146 if (CS_sig(context
) == WINE_CODE_SELECTOR
)
148 fprintf( stderr
, "Segmentation fault in Wine program (%x:%lx)."
150 CS_sig(context
), EIP_sig(context
) );
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
);
163 /**********************************************************************
166 static void SIGNAL_SetHandler( int sig
, void (*func
)(), int flags
)
169 struct sigaction sig_act
;
172 sig_act
.sa_handler
= func
;
173 sig_act
.sa_flags
= SA_RESTART
| (flags
) ? SA_NOMASK
: 0;
174 /* Point to the top of the stack, minus 4 just in case, and make
176 sig_act
.sa_restorer
=
177 (void (*)()) (((unsigned int)(cstack
) + sizeof(cstack
) - 4) & ~3);
178 ret
= wine_sigaction( sig
, &sig_act
, NULL
);
181 #if defined(__NetBSD__) || defined(__FreeBSD__)
183 sigemptyset(&sig_mask
);
184 sig_act
.sa_handler
= func
;
185 sig_act
.sa_flags
= SA_ONSTACK
;
186 sig_act
.sa_mask
= sig_mask
;
187 ret
= sigaction( sig
, &sig_act
, NULL
);
188 #endif /* __FreeBSD__ || __NetBSD__ */
190 #if defined (__svr4__) || defined(_SCO_DS)
192 sigemptyset(&sig_mask
);
193 sig_act
.sa_handler
= func
;
194 sig_act
.sa_flags
= SA_SIGINFO
| SA_ONSTACK
| SA_RESTART
;
195 sig_act
.sa_mask
= sig_mask
;
196 ret
= sigaction( sig
, &sig_act
, NULL
);
197 #endif /* __svr4__ || _SCO_DS */
201 sigemptyset(&sig_mask
);
202 sig_act
.sa_handler
= func
;
203 sig_act
.sa_flags
= 0; /* FIXME: EMX has only SA_ACK and SA_SYSV */
204 sig_act
.sa_mask
= sig_mask
;
205 ret
= sigaction( sig
, &sig_act
, NULL
);
210 perror( "sigaction" );
215 extern void stop_wait(int a
);
216 extern void WINSOCK_sigio(int a
);
219 /**********************************************************************
222 BOOL32
SIGNAL_Init(void)
224 #if defined(__NetBSD__) || defined(__FreeBSD__)
225 struct sigaltstack ss
;
227 if ((ss
.ss_sp
= malloc(MINSIGSTKSZ
)) == NULL
) {
228 fprintf(stderr
, "Unable to allocate signal stack (%d bytes)\n",
232 ss
.ss_size
= MINSIGSTKSZ
;
234 if (sigaltstack(&ss
, NULL
) < 0) {
238 #endif /* __FreeBSD__ || __NetBSD__ */
240 #if defined (__svr4__) || defined(_SCO_DS)
241 struct sigaltstack ss
;
243 if ((ss
.ss_sp
= malloc(SIGSTKSZ
) ) == NULL
) {
244 fprintf(stderr
, "Unable to allocate signal stack (%d bytes)\n",
248 ss
.ss_size
= SIGSTKSZ
;
250 if (sigaltstack(&ss
, NULL
) < 0) {
254 #endif /* __svr4__ || _SCO_DS */
256 SIGNAL_SetHandler( SIGALRM
, (void (*)())wine_timer
, 1);
257 SIGNAL_SetHandler( SIGINT
, (void (*)())SIGNAL_break
, 1);
258 SIGNAL_SetHandler( SIGCHLD
, (void (*)())SIGNAL_child
, 1);
259 SIGNAL_SetHandler( SIGSEGV
, (void (*)())SIGNAL_fault
, 1);
260 SIGNAL_SetHandler( SIGILL
, (void (*)())SIGNAL_fault
, 1);
261 SIGNAL_SetHandler( SIGFPE
, (void (*)())SIGNAL_fault
, 1);
262 SIGNAL_SetHandler( SIGTRAP
, (void (*)())SIGNAL_trap
, 1); /* debugger */
263 SIGNAL_SetHandler( SIGHUP
, (void (*)())SIGNAL_trap
, 1); /* forced break */
265 SIGNAL_SetHandler( SIGBUS
, (void (*)())SIGNAL_fault
, 1);
268 SIGNAL_SetHandler( SIGUSR2
, (void (*)())stop_wait
, 1); /* For IPC */
270 #ifndef __EMX__ /* FIXME */
271 SIGNAL_SetHandler( SIGIO
, (void (*)())WINSOCK_sigio
, 0);
277 /**********************************************************************
278 * SIGNAL_StartBIOSTimer
280 * Start the BIOS tick timer.
282 void SIGNAL_StartBIOSTimer(void)
284 #ifndef __EMX__ /* FIXME: Time don't work... Use BIOS directly instead */
285 struct itimerval vt_timer
;
286 static int timer_started
= 0;
288 if (timer_started
) return;
290 vt_timer
.it_interval
.tv_sec
= 0;
291 vt_timer
.it_interval
.tv_usec
= 54929;
292 vt_timer
.it_value
= vt_timer
.it_interval
;
294 setitimer(ITIMER_REAL
, &vt_timer
, NULL
);
298 /**********************************************************************
299 * SIGNAL_MaskAsyncEvents
301 void SIGNAL_MaskAsyncEvents( BOOL32 flag
)
305 #ifndef __EMX__ /* FIXME */
306 sigaddset(&set
, SIGIO
);
308 sigaddset(&set
, SIGUSR1
);
310 sigaddset(&set
, SIGUSR2
);
312 sigprocmask( (flag
) ? SIG_BLOCK
: SIG_UNBLOCK
, &set
, NULL
);
315 #endif /* ifndef WINELIB */