Piotr Caban : msvcrt: Added __pxcptinfoptrs implementation.
Alexandre Julliard
julliard at winehq.org
Tue Mar 5 12:59:17 CST 2013
Module: wine
Branch: master
Commit: 14a81773c7ce865dd6d919ddee89cad301985ab2
URL: http://source.winehq.org/git/wine.git/?a=commit;h=14a81773c7ce865dd6d919ddee89cad301985ab2
Author: Piotr Caban <piotr at 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);
More information about the wine-cvs
mailing list