[PATCH 3/3] msvcrt: Implement quick_exit and _crt_at_quick_exit

Fabian Maurer dark.shadow4 at web.de
Tue Jun 5 15:42:54 CDT 2018


Code taken from onexit logic and adapted-

Signed-off-by: Fabian Maurer <dark.shadow4 at web.de>
---
 dlls/msvcrt/exit.c | 48 ++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 46 insertions(+), 2 deletions(-)

diff --git a/dlls/msvcrt/exit.c b/dlls/msvcrt/exit.c
index 313a06ecd0..070a6753e8 100644
--- a/dlls/msvcrt/exit.c
+++ b/dlls/msvcrt/exit.c
@@ -30,8 +30,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
 #define UNLOCK_EXIT _munlock(_EXIT_LOCK1)
 
 static MSVCRT__onexit_t *MSVCRT_atexit_table = NULL;
+static MSVCRT__onexit_t *MSVCRT_atquickexit_table = NULL;
 static int MSVCRT_atexit_table_size = 0;
+static int MSVCRT_atquickexit_table_size = 0;
 static int MSVCRT_atexit_registered = 0; /* Points to free slot */
+static int MSVCRT_atquickexit_registered = 0; /* Points to free slot */
 static MSVCRT_purecall_handler purecall_handler = NULL;
 
 typedef struct MSVCRT__onexit_table_t
@@ -78,6 +81,22 @@ static void __MSVCRT__call_atexit(void)
   }
 }
 
+/* INTERNAL: call atexit functions */
+static void __MSVCRT__call_atquickexit(void)
+{
+  TRACE("%d atquickexit functions to call\n", MSVCRT_atquickexit_registered);
+
+  /* Last registered gets executed first */
+  while (MSVCRT_atquickexit_registered > 0)
+  {
+    MSVCRT_atquickexit_registered--;
+    TRACE("next is %p\n",MSVCRT_atquickexit_table[MSVCRT_atquickexit_registered]);
+    if (MSVCRT_atquickexit_table[MSVCRT_atquickexit_registered])
+      (*MSVCRT_atquickexit_table[MSVCRT_atquickexit_registered])();
+    TRACE("returned\n");
+  }
+}
+
 /*********************************************************************
  *		__dllonexit (MSVCRT.@)
  */
@@ -125,7 +144,8 @@ void CDECL MSVCRT__exit(int exitcode)
  */
 void CDECL MSVCRT_quick_exit(int exitcode)
 {
-  FIXME("partial stub: (%d)\n", exitcode);
+  TRACE("(%d)\n", exitcode);
+  __MSVCRT__call_atquickexit();
   MSVCRT__exit(exitcode);
 }
 
@@ -363,7 +383,31 @@ int CDECL MSVCRT_atexit(void (*func)(void))
  */
 int CDECL MSVCRT__crt_at_quick_exit(void (*func)(void))
 {
-  FIXME("stub: (%p)\n", func);
+  TRACE("(%p)\n",func);
+
+  if (!func)
+    return -1;
+
+  LOCK_EXIT;
+  if (MSVCRT_atquickexit_registered > MSVCRT_atquickexit_table_size - 1)
+  {
+    MSVCRT__onexit_t *newtable;
+    TRACE("expanding table\n");
+    newtable = MSVCRT_calloc(MSVCRT_atquickexit_table_size + 32, sizeof(void *));
+    if (!newtable)
+    {
+      TRACE("failed!\n");
+      UNLOCK_EXIT;
+      return -1;
+    }
+    memcpy (newtable, MSVCRT_atquickexit_table, MSVCRT_atquickexit_table_size*sizeof(void *));
+    MSVCRT_atquickexit_table_size += 32;
+    MSVCRT_free (MSVCRT_atquickexit_table);
+    MSVCRT_atquickexit_table = newtable;
+  }
+  MSVCRT_atquickexit_table[MSVCRT_atquickexit_registered] = (MSVCRT__onexit_t)func;
+  MSVCRT_atquickexit_registered++;
+  UNLOCK_EXIT;
   return 0;
 }
 
-- 
2.17.1




More information about the wine-devel mailing list