Implement signals.
This commit is contained in:
parent
6b7676a1e8
commit
e5b4a6973a
|
@ -2,6 +2,7 @@
|
|||
* msvcrt.dll exception handling
|
||||
*
|
||||
* Copyright 2000 Jon Griffiths
|
||||
* Copyright 2005 Juan Lang
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -37,12 +38,13 @@
|
|||
#include "wine/exception.h"
|
||||
#include "msvcrt.h"
|
||||
#include "excpt.h"
|
||||
#include "wincon.h"
|
||||
#include "msvcrt/float.h"
|
||||
#include "msvcrt/signal.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
|
||||
|
||||
typedef void (*MSVCRT_sig_handler_func)(void);
|
||||
|
||||
/* VC++ extensions to Win32 SEH */
|
||||
typedef struct _SCOPETABLE
|
||||
{
|
||||
|
@ -385,11 +387,144 @@ void __stdcall _seh_longjmp_unwind(struct MSVCRT___JUMP_BUFFER *jmp)
|
|||
}
|
||||
#endif /* i386 */
|
||||
|
||||
static __sighandler_t sighandlers[NSIG] = { SIG_DFL };
|
||||
|
||||
static BOOL WINAPI msvcrt_console_handler(DWORD ctrlType)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
|
||||
switch (ctrlType)
|
||||
{
|
||||
case CTRL_C_EVENT:
|
||||
if (sighandlers[SIGINT])
|
||||
{
|
||||
if (sighandlers[SIGINT] != SIG_IGN)
|
||||
sighandlers[SIGINT](SIGINT);
|
||||
ret = TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
typedef void (*float_handler)(int, int);
|
||||
|
||||
/* The exception codes are actually NTSTATUS values */
|
||||
struct
|
||||
{
|
||||
NTSTATUS status;
|
||||
int signal;
|
||||
} float_exception_map[] = {
|
||||
{ EXCEPTION_FLT_DENORMAL_OPERAND, _FPE_DENORMAL },
|
||||
{ EXCEPTION_FLT_DIVIDE_BY_ZERO, _FPE_ZERODIVIDE },
|
||||
{ EXCEPTION_FLT_INEXACT_RESULT, _FPE_INEXACT },
|
||||
{ EXCEPTION_FLT_INVALID_OPERATION, _FPE_INVALID },
|
||||
{ EXCEPTION_FLT_OVERFLOW, _FPE_OVERFLOW },
|
||||
{ EXCEPTION_FLT_STACK_CHECK, _FPE_STACKOVERFLOW },
|
||||
{ EXCEPTION_FLT_UNDERFLOW, _FPE_UNDERFLOW },
|
||||
};
|
||||
|
||||
static LONG WINAPI msvcrt_exception_filter(struct _EXCEPTION_POINTERS *except)
|
||||
{
|
||||
LONG ret = EXCEPTION_CONTINUE_SEARCH;
|
||||
|
||||
switch (except->ExceptionRecord->ExceptionCode)
|
||||
{
|
||||
case EXCEPTION_ACCESS_VIOLATION:
|
||||
if (sighandlers[SIGSEGV])
|
||||
{
|
||||
if (sighandlers[SIGSEGV] != SIG_IGN)
|
||||
sighandlers[SIGSEGV](SIGSEGV);
|
||||
ret = EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
break;
|
||||
/* According to
|
||||
* http://msdn.microsoft.com/library/en-us/vclib/html/_CRT_signal.asp
|
||||
* the FPE signal handler takes as a second argument the type of
|
||||
* floating point exception.
|
||||
*/
|
||||
case EXCEPTION_FLT_DENORMAL_OPERAND:
|
||||
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
|
||||
case EXCEPTION_FLT_INEXACT_RESULT:
|
||||
case EXCEPTION_FLT_INVALID_OPERATION:
|
||||
case EXCEPTION_FLT_OVERFLOW:
|
||||
case EXCEPTION_FLT_STACK_CHECK:
|
||||
case EXCEPTION_FLT_UNDERFLOW:
|
||||
if (sighandlers[SIGFPE])
|
||||
{
|
||||
if (sighandlers[SIGFPE] != SIG_IGN)
|
||||
{
|
||||
int i, float_signal = _FPE_INVALID;
|
||||
|
||||
float_handler handler = (float_handler)sighandlers[SIGFPE];
|
||||
for (i = 0; i < sizeof(float_exception_map) /
|
||||
sizeof(float_exception_map[0]); i++)
|
||||
if (float_exception_map[i].status ==
|
||||
except->ExceptionRecord->ExceptionCode)
|
||||
{
|
||||
float_signal = float_exception_map[i].signal;
|
||||
break;
|
||||
}
|
||||
handler(SIGFPE, float_signal);
|
||||
}
|
||||
ret = EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
break;
|
||||
case EXCEPTION_ILLEGAL_INSTRUCTION:
|
||||
if (sighandlers[SIGILL])
|
||||
{
|
||||
if (sighandlers[SIGILL] != SIG_IGN)
|
||||
sighandlers[SIGILL](SIGILL);
|
||||
ret = EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void msvcrt_init_signals(void)
|
||||
{
|
||||
SetConsoleCtrlHandler(msvcrt_console_handler, TRUE);
|
||||
SetUnhandledExceptionFilter(msvcrt_exception_filter);
|
||||
}
|
||||
|
||||
void msvcrt_free_signals(void)
|
||||
{
|
||||
SetConsoleCtrlHandler(msvcrt_console_handler, FALSE);
|
||||
SetUnhandledExceptionFilter(NULL);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* signal (MSVCRT.@)
|
||||
* MS signal handling is described here:
|
||||
* http://msdn.microsoft.com/library/en-us/vclib/html/_CRT_signal.asp
|
||||
* Some signals may never be generated except through an explicit call to
|
||||
* raise.
|
||||
*/
|
||||
void* MSVCRT_signal(int sig, MSVCRT_sig_handler_func func)
|
||||
__sighandler_t MSVCRT_signal(int sig, __sighandler_t func)
|
||||
{
|
||||
FIXME("(%d %p):stub\n", sig, func);
|
||||
return (void*)-1;
|
||||
__sighandler_t ret = SIG_ERR;
|
||||
|
||||
TRACE("(%d, %p)\n", sig, func);
|
||||
|
||||
if (func == SIG_ERR) return SIG_ERR;
|
||||
|
||||
switch (sig)
|
||||
{
|
||||
/* Cases handled internally. Note SIGTERM is never generated by Windows,
|
||||
* so we effectively mask it.
|
||||
*/
|
||||
case SIGABRT:
|
||||
case SIGFPE:
|
||||
case SIGILL:
|
||||
case SIGSEGV:
|
||||
case SIGINT:
|
||||
case SIGTERM:
|
||||
ret = sighandlers[sig];
|
||||
sighandlers[sig] = func;
|
||||
break;
|
||||
default:
|
||||
ret = SIG_ERR;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|||
msvcrt_init_io();
|
||||
msvcrt_init_console();
|
||||
msvcrt_init_args();
|
||||
msvcrt_init_signals();
|
||||
MSVCRT_setlocale(0, "C");
|
||||
TRACE("finished process init\n");
|
||||
break;
|
||||
|
@ -61,6 +62,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|||
msvcrt_free_io();
|
||||
msvcrt_free_console();
|
||||
msvcrt_free_args();
|
||||
msvcrt_free_signals();
|
||||
if (!msvcrt_free_tls())
|
||||
return FALSE;
|
||||
TRACE("finished process free\n");
|
||||
|
|
|
@ -125,6 +125,8 @@ extern void msvcrt_init_console(void);
|
|||
extern void msvcrt_free_console(void);
|
||||
extern void msvcrt_init_args(void);
|
||||
extern void msvcrt_free_args(void);
|
||||
extern void msvcrt_init_signals(void);
|
||||
extern void msvcrt_free_signals(void);
|
||||
|
||||
extern unsigned msvcrt_create_io_inherit_block(STARTUPINFOA*);
|
||||
|
||||
|
|
|
@ -291,6 +291,7 @@ MSVCRT_INCLUDES = \
|
|||
msvcrt/search.h \
|
||||
msvcrt/setjmp.h \
|
||||
msvcrt/share.h \
|
||||
msvcrt/signal.h \
|
||||
msvcrt/stddef.h \
|
||||
msvcrt/stdio.h \
|
||||
msvcrt/stdlib.h \
|
||||
|
|
|
@ -114,6 +114,19 @@ extern "C" {
|
|||
#define _FPCLASS_PN 0x0100 /* Positive Normal */
|
||||
#define _FPCLASS_PINF 0x0200 /* Positive Infinity */
|
||||
|
||||
/* floating point error signals */
|
||||
#define _FPE_INVALID 0x81
|
||||
#define _FPE_DENORMAL 0x82
|
||||
#define _FPE_ZERODIVIDE 0x83
|
||||
#define _FPE_OVERFLOW 0x84
|
||||
#define _FPE_UNDERFLOW 0x85
|
||||
#define _FPE_INEXACT 0x86
|
||||
#define _FPE_UNEMULATED 0x87
|
||||
#define _FPE_SQRTNEG 0x88
|
||||
#define _FPE_STACKOVERFLOW 0x8a
|
||||
#define _FPE_STACKUNDERFLOW 0x8b
|
||||
#define _FPE_EXPLICITGEN 0x8c
|
||||
|
||||
double _copysign (double, double);
|
||||
double _chgsign (double);
|
||||
double _scalb(double, long);
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Signal definitions
|
||||
*
|
||||
* Copyright 2005 Juan Lang
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#ifndef _WINE_SIGNAL_H
|
||||
#define _WINE_SIGNAL_H
|
||||
#ifndef __WINE_USE_MSVCRT
|
||||
#define __WINE_USE_MSVCRT
|
||||
#endif
|
||||
|
||||
#define SIGINT 2
|
||||
#define SIGILL 4
|
||||
#define SIGFPE 8
|
||||
#define SIGSEGV 11
|
||||
#define SIGTERM 15
|
||||
#define SIGBREAK 21
|
||||
#define SIGABRT 22
|
||||
|
||||
#define NSIG (SIGABRT + 1)
|
||||
|
||||
typedef void (*__sighandler_t)(int);
|
||||
|
||||
#define SIG_DFL ((__sighandler_t)0)
|
||||
#define SIG_IGN ((__sighandler_t)1)
|
||||
#define SIG_ERR ((__sighandler_t)-1)
|
||||
|
||||
__sighandler_t signal(int sig, __sighandler_t func);
|
||||
int raise(int sig);
|
||||
|
||||
#endif /* _WINE_SIGNAL_H */
|
Loading…
Reference in New Issue