Implement signals.

This commit is contained in:
Juan Lang 2005-05-13 17:44:28 +00:00 committed by Alexandre Julliard
parent 6b7676a1e8
commit e5b4a6973a
6 changed files with 203 additions and 5 deletions

View file

@ -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;
}

View file

@ -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");

View file

@ -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*);

View file

@ -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 \

View file

@ -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);

45
include/msvcrt/signal.h Normal file
View file

@ -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 */