From 14a81773c7ce865dd6d919ddee89cad301985ab2 Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Tue, 5 Mar 2013 11:05:42 +0100 Subject: [PATCH] msvcrt: Added __pxcptinfoptrs implementation. --- dlls/msvcrt/except.c | 45 +++++++++++++++++++++++++++++++++++++---- dlls/msvcrt/msvcrt.h | 3 ++- dlls/msvcrt/msvcrt.spec | 2 +- include/msvcrt/signal.h | 1 + 4 files changed, 45 insertions(+), 6 deletions(-) diff --git a/dlls/msvcrt/except.c b/dlls/msvcrt/except.c index c96623c0fb..32cf3b023c 100644 --- a/dlls/msvcrt/except.c +++ b/dlls/msvcrt/except.c @@ -61,6 +61,14 @@ static BOOL WINAPI msvcrt_console_handler(DWORD ctrlType) return ret; } +/********************************************************************* + * __pxcptinfoptrs (MSVCRT.@) + */ +void** CDECL MSVCRT___pxcptinfoptrs(void) +{ + return (void**)&msvcrt_get_thread_data()->xcptinfo; +} + typedef void (CDECL *float_handler)(int, int); /* The exception codes are actually NTSTATUS values */ @@ -93,8 +101,13 @@ static LONG WINAPI msvcrt_exception_filter(struct _EXCEPTION_POINTERS *except) { if (handler != MSVCRT_SIG_IGN) { + EXCEPTION_POINTERS **ep = (EXCEPTION_POINTERS**)MSVCRT___pxcptinfoptrs(), *old_ep; + + old_ep = *ep; + *ep = except; sighandlers[MSVCRT_SIGSEGV] = MSVCRT_SIG_DFL; handler(MSVCRT_SIGSEGV); + *ep = old_ep; } ret = EXCEPTION_CONTINUE_EXECUTION; } @@ -114,6 +127,7 @@ static LONG WINAPI msvcrt_exception_filter(struct _EXCEPTION_POINTERS *except) { if (handler != MSVCRT_SIG_IGN) { + EXCEPTION_POINTERS **ep = (EXCEPTION_POINTERS**)MSVCRT___pxcptinfoptrs(), *old_ep; unsigned int i; int float_signal = MSVCRT__FPE_INVALID; @@ -128,7 +142,11 @@ static LONG WINAPI msvcrt_exception_filter(struct _EXCEPTION_POINTERS *except) break; } } + + old_ep = *ep; + *ep = except; ((float_handler)handler)(MSVCRT_SIGFPE, float_signal); + *ep = old_ep; } ret = EXCEPTION_CONTINUE_EXECUTION; } @@ -139,8 +157,13 @@ static LONG WINAPI msvcrt_exception_filter(struct _EXCEPTION_POINTERS *except) { if (handler != MSVCRT_SIG_IGN) { + EXCEPTION_POINTERS **ep = (EXCEPTION_POINTERS**)MSVCRT___pxcptinfoptrs(), *old_ep; + + old_ep = *ep; + *ep = except; sighandlers[MSVCRT_SIGILL] = MSVCRT_SIG_DFL; handler(MSVCRT_SIGILL); + *ep = old_ep; } ret = EXCEPTION_CONTINUE_EXECUTION; } @@ -204,22 +227,36 @@ int CDECL MSVCRT_raise(int sig) switch (sig) { - case MSVCRT_SIGABRT: case MSVCRT_SIGFPE: case MSVCRT_SIGILL: case MSVCRT_SIGSEGV: - case MSVCRT_SIGINT: - case MSVCRT_SIGTERM: - case MSVCRT_SIGBREAK: handler = sighandlers[sig]; if (handler == MSVCRT_SIG_DFL) MSVCRT__exit(3); if (handler != MSVCRT_SIG_IGN) { + EXCEPTION_POINTERS **ep = (EXCEPTION_POINTERS**)MSVCRT___pxcptinfoptrs(), *old_ep; + sighandlers[sig] = MSVCRT_SIG_DFL; + + old_ep = *ep; + *ep = NULL; if (sig == MSVCRT_SIGFPE) ((float_handler)handler)(sig, MSVCRT__FPE_EXPLICITGEN); else handler(sig); + *ep = old_ep; + } + break; + case MSVCRT_SIGABRT: + case MSVCRT_SIGINT: + case MSVCRT_SIGTERM: + case MSVCRT_SIGBREAK: + handler = sighandlers[sig]; + if (handler == MSVCRT_SIG_DFL) MSVCRT__exit(3); + if (handler != MSVCRT_SIG_IGN) + { + sighandlers[sig] = MSVCRT_SIG_DFL; + handler(sig); } break; default: diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index 288d18da28..e2ff7a07d2 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -200,7 +200,8 @@ struct __thread_data { struct MSVCRT_tm *time_buffer; /* buffer for localtime/gmtime */ char *efcvt_buffer; /* buffer for ecvt/fcvt */ int unk3[2]; - void *unk4[4]; + void *unk4[3]; + EXCEPTION_POINTERS *xcptinfo; int fpecode; MSVCRT_pthreadmbcinfo mbcinfo; MSVCRT_pthreadlocinfo locinfo; diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index f5ef8b6761..2b01fc3c1f 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -250,7 +250,7 @@ @ cdecl __pctype_func() MSVCRT___pctype_func @ extern __pioinfo MSVCRT___pioinfo # stub __pwctype_func() -@ stub __pxcptinfoptrs() +@ cdecl __pxcptinfoptrs() MSVCRT___pxcptinfoptrs @ cdecl __set_app_type(long) MSVCRT___set_app_type @ extern __setlc_active MSVCRT___setlc_active @ cdecl __setusermatherr(ptr) MSVCRT___setusermatherr diff --git a/include/msvcrt/signal.h b/include/msvcrt/signal.h index d9f72cc61e..42d2bfe4ce 100644 --- a/include/msvcrt/signal.h +++ b/include/msvcrt/signal.h @@ -42,6 +42,7 @@ typedef void (__cdecl *__sighandler_t)(int); #define SIG_IGN ((__sighandler_t)1) #define SIG_ERR ((__sighandler_t)-1) +void** __cdecl __pxcptinfoptrs(void); __sighandler_t __cdecl signal(int sig, __sighandler_t func); int __cdecl raise(int sig); -- 2.32.0.93.g670b81a890