From: Fabian Maurer Subject: [PATCH 3/3] msvcrt: Implement quick_exit and _crt_at_quick_exit Message-Id: <20180605204254.19205-3-dark.shadow4@web.de> Date: Tue, 5 Jun 2018 22:42:54 +0200 In-Reply-To: <20180605204254.19205-1-dark.shadow4@web.de> References: <20180605204254.19205-1-dark.shadow4@web.de> Code taken from onexit logic and adapted- Signed-off-by: Fabian Maurer --- 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