11 #include <sys/timeb.h>
12 #include <sys/types.h>
15 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__svr4__) || defined(_SCO_DS)
17 #include <sys/syscall.h>
19 #include <sys/param.h>
27 #include "registers.h"
31 #if !defined(BSD4_4) || defined(linux) || defined(__FreeBSD__)
36 extern void ___sig_restore();
37 extern void ___masksig_restore();
39 /* Similar to the sigaction function in libc, except it leaves alone the
43 wine_sigaction(int sig
,struct sigaction
* new, struct sigaction
* old
)
45 __asm__("int $0x80":"=a" (sig
)
46 :"0" (SYS_sigaction
),"b" (sig
),"c" (new),"d" (old
));
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 wait4( 0, NULL
, WNOHANG
, NULL
);
106 /**********************************************************************
112 static void SIGNAL_trap(int signal
, SIGCONTEXT context_struct
)
114 SIGCONTEXT
*context
= &context_struct
;
115 #elif defined(__svr4__) || defined(_SCO_DS)
116 static void SIGNAL_trap(int signal
, void *siginfo
, SIGCONTEXT
*context
)
119 static void SIGNAL_trap(int signal
, int code
, SIGCONTEXT
*context
)
122 wine_debug( signal
, context
); /* Enter our debugger */
126 /**********************************************************************
132 static void SIGNAL_fault(int signal
, SIGCONTEXT context_struct
)
134 SIGCONTEXT
*context
= &context_struct
;
135 #elif defined(__svr4__) || defined(_SCO_DS)
136 static void SIGNAL_fault(int signal
, void *siginfo
, SIGCONTEXT
*context
)
139 static void SIGNAL_fault(int signal
, int code
, SIGCONTEXT
*context
)
142 if (CS_reg(context
) == WINE_CODE_SELECTOR
)
144 fprintf( stderr
, "Segmentation fault in Wine program (%x:%lx)."
146 CS_reg(context
), EIP_reg(context
) );
150 if (INSTR_EmulateInstruction( context
)) return;
151 fprintf( stderr
, "Segmentation fault in Windows program %x:%lx.\n",
152 CS_reg(context
), EIP_reg(context
) );
154 wine_debug( signal
, context
);
158 /**********************************************************************
161 static void SIGNAL_SetHandler( int sig
, void (*func
)(), int flags
)
164 struct sigaction sig_act
;
167 sig_act
.sa_handler
= func
;
168 sig_act
.sa_flags
= SA_RESTART
| (flags
) ? SA_NOMASK
: 0;
169 /* Point to the top of the stack, minus 4 just in case, and make
171 sig_act
.sa_restorer
=
172 (void (*)()) (((unsigned int)(cstack
) + sizeof(cstack
) - 4) & ~3);
173 ret
= wine_sigaction( sig
, &sig_act
, NULL
);
176 #if defined(__NetBSD__) || defined(__FreeBSD__)
178 sigemptyset(&sig_mask
);
179 sig_act
.sa_handler
= func
;
180 sig_act
.sa_flags
= SA_ONSTACK
;
181 sig_act
.sa_mask
= sig_mask
;
182 ret
= sigaction( sig
, &sig_act
, NULL
);
183 #endif /* __FreeBSD__ || __NetBSD__ */
185 #if defined (__svr4__) || defined(_SCO_DS)
187 sigemptyset(&sig_mask
);
188 sig_act
.sa_handler
= func
;
189 sig_act
.sa_flags
= SA_SIGINFO
| SA_ONSTACK
| SA_RESTART
;
190 sig_act
.sa_mask
= sig_mask
;
191 ret
= sigaction( sig
, &sig_act
, NULL
);
192 #endif /* __svr4__ || _SCO_DS */
196 perror( "sigaction" );
201 extern void stop_wait(int a
);
202 extern void WINSOCK_sigio(int a
);
205 /**********************************************************************
208 BOOL32
SIGNAL_Init(void)
210 #if defined(__NetBSD__) || defined(__FreeBSD__)
211 struct sigaltstack ss
;
213 if ((ss
.ss_sp
= malloc(MINSIGSTKSZ
)) == NULL
) {
214 fprintf(stderr
, "Unable to allocate signal stack (%d bytes)\n",
218 ss
.ss_size
= MINSIGSTKSZ
;
220 if (sigaltstack(&ss
, NULL
) < 0) {
224 #endif /* __FreeBSD__ || __NetBSD__ */
226 #if defined (__svr4__) || defined(_SCO_DS)
227 struct sigaltstack ss
;
229 if ((ss
.ss_sp
= malloc(SIGSTKSZ
) ) == NULL
) {
230 fprintf(stderr
, "Unable to allocate signal stack (%d bytes)\n",
234 ss
.ss_size
= SIGSTKSZ
;
236 if (sigaltstack(&ss
, NULL
) < 0) {
240 #endif /* __svr4__ || _SCO_DS */
242 SIGNAL_SetHandler( SIGALRM
, (void (*)())wine_timer
, 1);
243 SIGNAL_SetHandler( SIGINT
, (void (*)())SIGNAL_break
, 1);
244 SIGNAL_SetHandler( SIGCHLD
, (void (*)())SIGNAL_child
, 1);
245 SIGNAL_SetHandler( SIGSEGV
, (void (*)())SIGNAL_fault
, 1);
246 SIGNAL_SetHandler( SIGILL
, (void (*)())SIGNAL_fault
, 1);
247 SIGNAL_SetHandler( SIGFPE
, (void (*)())SIGNAL_fault
, 1);
248 SIGNAL_SetHandler( SIGTRAP
, (void (*)())SIGNAL_trap
, 1); /* debugger */
249 SIGNAL_SetHandler( SIGHUP
, (void (*)())SIGNAL_trap
, 1); /* forced break */
251 SIGNAL_SetHandler( SIGBUS
, (void (*)())SIGNAL_fault
, 1);
254 SIGNAL_SetHandler( SIGUSR2
, (void (*)())stop_wait
, 1); /* For IPC */
256 SIGNAL_SetHandler( SIGIO
, (void (*)())WINSOCK_sigio
, 0);
261 /**********************************************************************
262 * SIGNAL_StartBIOSTimer
264 * Start the BIOS tick timer.
266 void SIGNAL_StartBIOSTimer(void)
268 struct itimerval vt_timer
;
269 static int timer_started
= 0;
271 if (timer_started
) return;
273 vt_timer
.it_interval
.tv_sec
= 0;
274 vt_timer
.it_interval
.tv_usec
= 54929;
275 vt_timer
.it_value
= vt_timer
.it_interval
;
277 setitimer(ITIMER_REAL
, &vt_timer
, NULL
);
280 /**********************************************************************
281 * SIGNAL_MaskAsyncEvents
283 void SIGNAL_MaskAsyncEvents( BOOL32 flag
)
287 sigaddset(&set
, SIGIO
);
288 sigaddset(&set
, SIGUSR1
);
290 sigaddset(&set
, SIGUSR2
);
292 sigprocmask( (flag
) ? SIG_BLOCK
: SIG_UNBLOCK
, &set
, NULL
);
295 #endif /* ifndef WINELIB */