Signed-off-by: Fabian Maurer dark.shadow4@web.de --- dlls/msvcrt/exit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcrt/exit.c b/dlls/msvcrt/exit.c index 4109f052771..77743d5b01f 100644 --- a/dlls/msvcrt/exit.c +++ b/dlls/msvcrt/exit.c @@ -397,7 +397,7 @@ void CDECL MSVCRT_exit(int exitcode) /********************************************************************* * atexit (MSVCRT.@) */ -int CDECL MSVCRT_atexit(void (*func)(void)) +int CDECL MSVCRT_atexit(void (__cdecl *func)(void)) { TRACE("(%p)\n", func); return MSVCRT__onexit((MSVCRT__onexit_t)func) == (MSVCRT__onexit_t)func ? 0 : -1; @@ -408,7 +408,7 @@ int CDECL MSVCRT_atexit(void (*func)(void)) /********************************************************************* * _crt_atexit (UCRTBASE.@) */ -int CDECL MSVCRT__crt_atexit(void (*func)(void)) +int CDECL MSVCRT__crt_atexit(void (__cdecl *func)(void)) { TRACE("(%p)\n", func); return MSVCRT__onexit((MSVCRT__onexit_t)func) == (MSVCRT__onexit_t)func ? 0 : -1;
Fixes bug 45295.
Signed-off-by: Fabian Maurer dark.shadow4@web.de --- .../api-ms-win-crt-runtime-l1-1-0.spec | 2 +- dlls/msvcr120/tests/msvcr120.c | 8 ++++++++ dlls/msvcrt/exit.c | 9 +++++++++ dlls/ucrtbase/tests/misc.c | 8 ++++++++ dlls/ucrtbase/ucrtbase.spec | 2 +- 5 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec b/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec index 24014a65bac..4bc8df768d1 100644 --- a/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec +++ b/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec @@ -28,7 +28,7 @@ @ cdecl _control87(long long) ucrtbase._control87 @ cdecl _controlfp(long long) ucrtbase._controlfp @ cdecl _controlfp_s(ptr long long) ucrtbase._controlfp_s -@ stub _crt_at_quick_exit +@ cdecl _crt_at_quick_exit(ptr) ucrtbase._crt_at_quick_exit @ cdecl _crt_atexit(ptr) ucrtbase._crt_atexit @ cdecl _crt_debugger_hook(long) ucrtbase._crt_debugger_hook @ cdecl _endthread() ucrtbase._endthread diff --git a/dlls/msvcr120/tests/msvcr120.c b/dlls/msvcr120/tests/msvcr120.c index 85e83a6c65a..a816ad6e7c5 100644 --- a/dlls/msvcr120/tests/msvcr120.c +++ b/dlls/msvcr120/tests/msvcr120.c @@ -184,6 +184,7 @@ static _locale_t (__cdecl *p_wcreate_locale)(int, const wchar_t *); static void (__cdecl *p_free_locale)(_locale_t); static unsigned short (__cdecl *p_wctype)(const char*); static int (__cdecl *p_vsscanf)(const char*, const char *, __ms_va_list valist); +static int (__cdecl *p_crt_at_quick_exit)(void (__cdecl *func)(void));
/* make sure we use the correct errno */ #undef errno @@ -238,6 +239,7 @@ static BOOL init(void) p_errno = (void*)GetProcAddress(module, "_errno"); p_wcreate_locale = (void*)GetProcAddress(module, "_wcreate_locale"); p_free_locale = (void*)GetProcAddress(module, "_free_locale"); + p_crt_at_quick_exit = (void*)GetProcAddress(module, "_crt_at_quick_exit"); SET(p_wctype, "wctype"); SET(p_fegetenv, "fegetenv"); SET(p__clearfp, "_clearfp"); @@ -935,6 +937,11 @@ static void test_vsscanf(void) ok(v == 10, "got %d.\n", v); }
+static void test_quick_exit(void) +{ + ok(p_crt_at_quick_exit == NULL, "_crt_at_quick_exit should not exist in this version\n"); +} + START_TEST(msvcr120) { if (!init()) return; @@ -953,4 +960,5 @@ START_TEST(msvcr120) test__Condition_variable(); test_wctype(); test_vsscanf(); + test_quick_exit(); } diff --git a/dlls/msvcrt/exit.c b/dlls/msvcrt/exit.c index 77743d5b01f..3cce64dc75b 100644 --- a/dlls/msvcrt/exit.c +++ b/dlls/msvcrt/exit.c @@ -405,6 +405,15 @@ int CDECL MSVCRT_atexit(void (__cdecl *func)(void))
#if _MSVCR_VER>=140
+/********************************************************************* + * _crt_at_quick_exit (UCRTBASE.@) + */ +int CDECL MSVCRT__crt_at_quick_exit(void (__cdecl *func)(void)) +{ + FIXME("stub: (%p)\n", func); + return -1; +} + /********************************************************************* * _crt_atexit (UCRTBASE.@) */ diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c index 1c56f731335..14b05ffc137 100644 --- a/dlls/ucrtbase/tests/misc.c +++ b/dlls/ucrtbase/tests/misc.c @@ -127,6 +127,7 @@ static int* (CDECL *p_errno)(void); static char* (CDECL *p_asctime)(const struct tm *); static void (CDECL *p_exit)(int); static int (CDECL *p__crt_atexit)(void (CDECL*)(void)); +static int (__cdecl *p_crt_at_quick_exit)(void (__cdecl *func)(void));
static void test__initialize_onexit_table(void) { @@ -433,6 +434,7 @@ static BOOL init(void) p_asctime = (void*)GetProcAddress(module, "asctime"); p__crt_atexit = (void*)GetProcAddress(module, "_crt_atexit"); p_exit = (void*)GetProcAddress(module, "exit"); + p_crt_at_quick_exit = (void*)GetProcAddress(module, "_crt_at_quick_exit");
return TRUE; } @@ -815,6 +817,11 @@ static void test_call_exit(void) p_exit(0); }
+static void test_quick_exit(void) +{ + ok(p_crt_at_quick_exit != NULL, "_crt_at_quick_exit should exist in this version\n"); +} + START_TEST(misc) { int arg_c; @@ -845,4 +852,5 @@ START_TEST(misc) test_math_errors(); test_asctime(); test_exit(arg_v[0]); + test_quick_exit(); } diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index 236b0d526d7..3cb355506a2 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -240,7 +240,7 @@ @ cdecl _cputws(wstr) @ cdecl _creat(str long) MSVCRT__creat @ cdecl _create_locale(long str) MSVCRT__create_locale -@ stub _crt_at_quick_exit +@ cdecl _crt_at_quick_exit(ptr) MSVCRT__crt_at_quick_exit @ cdecl _crt_atexit(ptr) MSVCRT__crt_atexit @ cdecl _crt_debugger_hook(long) MSVCRT__crt_debugger_hook @ cdecl _ctime32(ptr) MSVCRT__ctime32
Follow-up issue to bug 45295.
Signed-off-by: Fabian Maurer dark.shadow4@web.de
# Conflicts: # dlls/msvcr120/tests/msvcr120.c # dlls/ucrtbase/tests/misc.c --- .../api-ms-win-crt-runtime-l1-1-0.spec | 2 +- dlls/msvcr120/tests/msvcr120.c | 3 +++ dlls/msvcrt/exit.c | 9 +++++++++ dlls/ucrtbase/tests/misc.c | 3 +++ dlls/ucrtbase/ucrtbase.spec | 2 +- 5 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec b/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec index 4bc8df768d1..74d682b33bf 100644 --- a/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec +++ b/dlls/api-ms-win-crt-runtime-l1-1-0/api-ms-win-crt-runtime-l1-1-0.spec @@ -97,7 +97,7 @@ @ cdecl fesetround(long) ucrtbase.fesetround @ stub fetestexcept @ cdecl perror(str) ucrtbase.perror -@ stub quick_exit +@ cdecl quick_exit(long) ucrtbase.quick_exit @ cdecl raise(long) ucrtbase.raise @ cdecl set_terminate(ptr) ucrtbase.set_terminate @ cdecl signal(long long) ucrtbase.signal diff --git a/dlls/msvcr120/tests/msvcr120.c b/dlls/msvcr120/tests/msvcr120.c index a816ad6e7c5..e9734de4f5e 100644 --- a/dlls/msvcr120/tests/msvcr120.c +++ b/dlls/msvcr120/tests/msvcr120.c @@ -185,6 +185,7 @@ static void (__cdecl *p_free_locale)(_locale_t); static unsigned short (__cdecl *p_wctype)(const char*); static int (__cdecl *p_vsscanf)(const char*, const char *, __ms_va_list valist); static int (__cdecl *p_crt_at_quick_exit)(void (__cdecl *func)(void)); +static void (__cdecl *p_quick_exit)(int exitcode);
/* make sure we use the correct errno */ #undef errno @@ -240,6 +241,7 @@ static BOOL init(void) p_wcreate_locale = (void*)GetProcAddress(module, "_wcreate_locale"); p_free_locale = (void*)GetProcAddress(module, "_free_locale"); p_crt_at_quick_exit = (void*)GetProcAddress(module, "_crt_at_quick_exit"); + p_quick_exit = (void*)GetProcAddress(module, "quick_exit"); SET(p_wctype, "wctype"); SET(p_fegetenv, "fegetenv"); SET(p__clearfp, "_clearfp"); @@ -940,6 +942,7 @@ static void test_vsscanf(void) static void test_quick_exit(void) { ok(p_crt_at_quick_exit == NULL, "_crt_at_quick_exit should not exist in this version\n"); + ok(p_quick_exit == NULL, "quick_exit should not exist in this version."); }
START_TEST(msvcr120) diff --git a/dlls/msvcrt/exit.c b/dlls/msvcrt/exit.c index 3cce64dc75b..6dcf0db2731 100644 --- a/dlls/msvcrt/exit.c +++ b/dlls/msvcrt/exit.c @@ -414,6 +414,15 @@ int CDECL MSVCRT__crt_at_quick_exit(void (__cdecl *func)(void)) return -1; }
+/********************************************************************* + * quick_exit (MSVCRT.@) + */ +void CDECL MSVCRT_quick_exit(int exitcode) +{ + FIXME("partial stub: (%d)\n", exitcode); + MSVCRT__exit(exitcode); +} + /********************************************************************* * _crt_atexit (UCRTBASE.@) */ diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c index 14b05ffc137..54ae4e94714 100644 --- a/dlls/ucrtbase/tests/misc.c +++ b/dlls/ucrtbase/tests/misc.c @@ -128,6 +128,7 @@ static char* (CDECL *p_asctime)(const struct tm *); static void (CDECL *p_exit)(int); static int (CDECL *p__crt_atexit)(void (CDECL*)(void)); static int (__cdecl *p_crt_at_quick_exit)(void (__cdecl *func)(void)); +static void (__cdecl *p_quick_exit)(int exitcode);
static void test__initialize_onexit_table(void) { @@ -435,6 +436,7 @@ static BOOL init(void) p__crt_atexit = (void*)GetProcAddress(module, "_crt_atexit"); p_exit = (void*)GetProcAddress(module, "exit"); p_crt_at_quick_exit = (void*)GetProcAddress(module, "_crt_at_quick_exit"); + p_quick_exit = (void*)GetProcAddress(module, "quick_exit");
return TRUE; } @@ -820,6 +822,7 @@ static void test_call_exit(void) static void test_quick_exit(void) { ok(p_crt_at_quick_exit != NULL, "_crt_at_quick_exit should exist in this version\n"); + ok(p_quick_exit != NULL, "quick_exit should exist in this version\n"); }
START_TEST(misc) diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index 3cb355506a2..9d993e90b7a 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -2454,7 +2454,7 @@ @ cdecl putwchar(long) MSVCRT__fputwchar @ cdecl qsort(ptr long long ptr) MSVCRT_qsort @ cdecl qsort_s(ptr long long ptr ptr) MSVCRT_qsort_s -@ stub quick_exit +@ cdecl quick_exit(long) MSVCRT_quick_exit @ cdecl raise(long) MSVCRT_raise @ cdecl rand() MSVCRT_rand @ cdecl rand_s(ptr) MSVCRT_rand_s
Signed-off-by: Fabian Maurer dark.shadow4@web.de --- dlls/msvcrt/exit.c | 19 +++++++++-- dlls/ucrtbase/tests/misc.c | 67 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 80 insertions(+), 6 deletions(-)
diff --git a/dlls/msvcrt/exit.c b/dlls/msvcrt/exit.c index 6dcf0db2731..4165cf66bb9 100644 --- a/dlls/msvcrt/exit.c +++ b/dlls/msvcrt/exit.c @@ -40,6 +40,10 @@ typedef struct MSVCRT__onexit_table_t
static MSVCRT__onexit_table_t MSVCRT_atexit_table;
+#if _MSVCR_VER>=140 +static MSVCRT__onexit_table_t MSVCRT_quick_exit_table; +#endif + typedef void (__stdcall *_tls_callback_type)(void*,ULONG,void*); static _tls_callback_type tls_atexit_callback;
@@ -410,8 +414,14 @@ int CDECL MSVCRT_atexit(void (__cdecl *func)(void)) */ int CDECL MSVCRT__crt_at_quick_exit(void (__cdecl *func)(void)) { - FIXME("stub: (%p)\n", func); - return -1; + TRACE("(%p)\n", func); + + if (!func) + return -1; + + register_onexit_function(&MSVCRT_quick_exit_table, (MSVCRT__onexit_t)func); + + return 0; }
/********************************************************************* @@ -419,7 +429,10 @@ int CDECL MSVCRT__crt_at_quick_exit(void (__cdecl *func)(void)) */ void CDECL MSVCRT_quick_exit(int exitcode) { - FIXME("partial stub: (%d)\n", exitcode); + TRACE("(%d)\n", exitcode); + + execute_onexit_table(&MSVCRT_quick_exit_table); + MSVCRT__exit(exitcode); }
diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c index 54ae4e94714..09df67535ff 100644 --- a/dlls/ucrtbase/tests/misc.c +++ b/dlls/ucrtbase/tests/misc.c @@ -778,10 +778,11 @@ static void test_exit(const char *argv0) PROCESS_INFORMATION proc; STARTUPINFOA startup = {0}; char path[MAX_PATH]; - HANDLE exit_event; + HANDLE exit_event, quick_exit_event; DWORD ret;
exit_event = CreateEventA(NULL, FALSE, FALSE, "exit_event"); + quick_exit_event = CreateEventA(NULL, FALSE, FALSE, "quick_exit_event");
sprintf(path, "%s misc exit", argv0); startup.cb = sizeof(startup); @@ -790,11 +791,14 @@ static void test_exit(const char *argv0)
ret = WaitForSingleObject(exit_event, 0); ok(ret == WAIT_OBJECT_0, "exit_event was not set (%x)\n", ret); + ret = WaitForSingleObject(quick_exit_event, 0); + ok(ret == WAIT_TIMEOUT, "quick_exit_event should not have be set (%x)\n", ret);
CloseHandle(exit_event); }
static int atexit_called; + static void CDECL at_exit_func1(void) { HANDLE exit_event = CreateEventA(NULL, FALSE, FALSE, "exit_event"); @@ -819,10 +823,65 @@ static void test_call_exit(void) p_exit(0); }
-static void test_quick_exit(void) +static int atquick_exit_called; + +static void CDECL at_quick_exit_func1(void) +{ + HANDLE quick_exit_event = CreateEventA(NULL, FALSE, FALSE, "quick_exit_event"); + + ok(quick_exit_event != NULL, "CreateEvent failed: %d\n", GetLastError()); + ok(atquick_exit_called == 1, "atquick_exit_called = %d\n", atquick_exit_called); + atquick_exit_called++; + SetEvent(quick_exit_event); + CloseHandle(quick_exit_event); +} + +static void CDECL at_quick_exit_func2(void) { + ok(!atquick_exit_called, "atquick_exit_called = %d\n", atquick_exit_called); + atquick_exit_called++; +} + +static void test_call_quick_exit(void) +{ + ok(!p_crt_at_quick_exit(at_quick_exit_func1), "_crt_at_quick_exit failed\n"); + ok(!p_crt_at_quick_exit(at_quick_exit_func2), "_crt_at_quick_exit failed\n"); + p_quick_exit(0); +} + +static void test_quick_exit(const char *argv0) +{ + PROCESS_INFORMATION proc; + STARTUPINFOA startup = {0}; + char path[MAX_PATH]; + HANDLE exit_event, quick_exit_event; + DWORD ret; + int result; + ok(p_crt_at_quick_exit != NULL, "_crt_at_quick_exit should exist in this version\n"); ok(p_quick_exit != NULL, "quick_exit should exist in this version\n"); + + result = p_crt_at_quick_exit(at_quick_exit_func2); + ok(result == 0, "Expected success."); + + result = p_crt_at_quick_exit(NULL); + ok(result == -1, "Expected failure."); + + + exit_event = CreateEventA(NULL, FALSE, FALSE, "exit_event"); + quick_exit_event = CreateEventA(NULL, FALSE, FALSE, "quick_exit_event"); + + sprintf(path, "%s misc quick_exit", argv0); + startup.cb = sizeof(startup); + CreateProcessA(NULL, path, NULL, NULL, TRUE, 0, NULL, NULL, &startup, &proc); + winetest_wait_child_process(proc.hProcess); + + ret = WaitForSingleObject(quick_exit_event, 0); + ok(ret == WAIT_OBJECT_0, "quick_exit_event was not set (%x)\n", ret); + ret = WaitForSingleObject(exit_event, 0); + ok(ret == WAIT_TIMEOUT, "exit_event should not have be set (%x)\n", ret); + + CloseHandle(exit_event); }
START_TEST(misc) @@ -839,6 +898,8 @@ START_TEST(misc) test__get_narrow_winmain_command_line(NULL); else if(!strcmp(arg_v[2], "exit")) test_call_exit(); + else if(!strcmp(arg_v[2], "quick_exit")) + test_call_quick_exit(); return; }
@@ -855,5 +916,5 @@ START_TEST(misc) test_math_errors(); test_asctime(); test_exit(arg_v[0]); - test_quick_exit(); + test_quick_exit(arg_v[0]); }
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check? Full results can be found at https://testbot.winehq.org/JobDetails.pl?Key=39537
Your paranoid android.
=== w7u (32 bit misc) === misc.c:868: Test failed: Expected failure.0d24:misc: 197743 tests executed (0 marked as todo, 1 failure), 0 skipped. ucrtbase:misc has no test summary line (early exit of the main process?) ucrtbase:misc has unaccounted for failure messages
=== w1064 (32 bit misc) === misc.c:868: Test failed: Expected failure.0df4:misc: 197743 tests executed (0 marked as todo, 1 failure), 0 skipped. ucrtbase:misc has no test summary line (early exit of the main process?) ucrtbase:misc has unaccounted for failure messages
=== w1064 (64 bit misc) === misc.c:868: Test failed: Expected failure.0e04:misc: 197743 tests executed (0 marked as todo, 1 failure), 0 skipped. ucrtbase:misc has no test summary line (early exit of the main process?) ucrtbase:misc has unaccounted for failure messages