Module: wine Branch: master Commit: 14a81773c7ce865dd6d919ddee89cad301985ab2 URL: http://source.winehq.org/git/wine.git/?a=commit;h=14a81773c7ce865dd6d919ddee...
Author: Piotr Caban piotr@codeweavers.com Date: Tue Mar 5 11:05:42 2013 +0100
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 c96623c..32cf3b0 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 288d18d..e2ff7a0 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 f5ef8b6..2b01fc3 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 d9f72cc..42d2bfe 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);