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