11 #include <sys/timeb.h>
12 #include <sys/types.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>
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 /* Similar to the sigaction function in libc, except it leaves alone the
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
));
53 extern BOOL32
INSTR_EmulateInstruction( SIGCONTEXT
*context
);
55 /**********************************************************************
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
)
67 static void wine_timer(int signal
, int code
, SIGCONTEXT
*context
)
70 /* Should do real-time timers here */
75 /**********************************************************************
78 * Handle Ctrl-C and such
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
)
88 static void SIGNAL_break(int signal
, int code
, SIGCONTEXT
*context
)
91 if (Options
.debug
) wine_debug( signal
, context
); /* Enter our debugger */
95 /**********************************************************************
98 * wait4 terminated child processes
100 static void SIGNAL_child(void)
102 #if defined(__svr4__) || defined(__EMX__)
105 wait4( 0, NULL
, WNOHANG
, NULL
);
110 /**********************************************************************
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
)
123 static void SIGNAL_trap(int signal
, int code
, SIGCONTEXT
*context
)
126 wine_debug( signal
, context
); /* Enter our debugger */
130 /**********************************************************************
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
)
143 static void SIGNAL_fault(int signal
, int code
, SIGCONTEXT
*context
)
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
);
162 /**********************************************************************
165 static void SIGNAL_SetHandler( int sig
, void (*func
)(), int flags
)
168 struct sigaction sig_act
;
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
175 sig_act
.sa_restorer
=
176 (void (*)()) (((unsigned int)(cstack
) + sizeof(cstack
) - 4) & ~3);
177 ret
= wine_sigaction( sig
, &sig_act
, NULL
);
180 #if defined(__NetBSD__) || defined(__FreeBSD__)
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)
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 */
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
);
209 perror( "sigaction" );
214 extern void stop_wait(int a
);
215 extern void WINSOCK_sigio(int a
);
218 /**********************************************************************
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",
231 ss
.ss_size
= MINSIGSTKSZ
;
233 if (sigaltstack(&ss
, NULL
) < 0) {
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",
247 ss
.ss_size
= SIGSTKSZ
;
249 if (sigaltstack(&ss
, NULL
) < 0) {
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 */
264 SIGNAL_SetHandler( SIGBUS
, (void (*)())SIGNAL_fault
, 1);
267 SIGNAL_SetHandler( SIGUSR2
, (void (*)())stop_wait
, 1); /* For IPC */
269 #ifndef __EMX__ /* FIXME */
270 SIGNAL_SetHandler( SIGIO
, (void (*)())WINSOCK_sigio
, 0);
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;
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
);
297 /**********************************************************************
298 * SIGNAL_MaskAsyncEvents
300 void SIGNAL_MaskAsyncEvents( BOOL32 flag
)
304 #ifndef __EMX__ /* FIXME */
305 sigaddset(&set
, SIGIO
);
307 sigaddset(&set
, SIGUSR1
);
309 sigaddset(&set
, SIGUSR2
);
311 sigprocmask( (flag
) ? SIG_BLOCK
: SIG_UNBLOCK
, &set
, NULL
);
314 #endif /* ifndef WINELIB */