diff --git a/AK/Windows.h b/AK/Windows.h index bc5076b2a6..8778b89203 100644 --- a/AK/Windows.h +++ b/AK/Windows.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2024, stasoid + * Copyright (c) 2025, ayeteadoe * * SPDX-License-Identifier: BSD-2-Clause */ @@ -9,6 +10,7 @@ #pragma once +#include #include #ifdef AK_OS_WINDOWS // needed for Swift @@ -18,4 +20,40 @@ # undef IN # pragma comment(lib, "ws2_32.lib") # include +# include + +inline void initiate_wsa() +{ + WSADATA wsa; + WORD version = MAKEWORD(2, 2); + int rc = WSAStartup(version, &wsa); + VERIFY(rc == 0 && wsa.wVersion == version); +} + +inline void terminate_wsa() +{ + int rc = WSACleanup(); + VERIFY(rc == 0); +} + +static void invalid_parameter_handler(wchar_t const*, wchar_t const*, wchar_t const*, unsigned int, uintptr_t) +{ +} + +inline void override_crt_invalid_parameter_handler() +{ + // Make _get_osfhandle return -1 instead of crashing on invalid fd in release (debug still __debugbreak's) + _set_invalid_parameter_handler(invalid_parameter_handler); +} + +inline void windows_init() +{ + initiate_wsa(); + override_crt_invalid_parameter_handler(); +} + +inline void windows_shutdown() +{ + terminate_wsa(); +} #endif diff --git a/Libraries/LibCore/SystemWindows.cpp b/Libraries/LibCore/SystemWindows.cpp index 7a0eda67b0..6d1e51f080 100644 --- a/Libraries/LibCore/SystemWindows.cpp +++ b/Libraries/LibCore/SystemWindows.cpp @@ -23,24 +23,6 @@ namespace Core::System { int windows_socketpair(SOCKET socks[2], int make_overlapped); -static void invalid_parameter_handler(wchar_t const*, wchar_t const*, wchar_t const*, unsigned int, uintptr_t) -{ -} - -static int init_crt_and_wsa() -{ - WSADATA wsa; - WORD version = MAKEWORD(2, 2); - int rc = WSAStartup(version, &wsa); - VERIFY(!rc && wsa.wVersion == version); - - // Make _get_osfhandle return -1 instead of crashing on invalid fd in release (debug still __debugbreak's) - _set_invalid_parameter_handler(invalid_parameter_handler); - return 0; -} - -static auto dummy = init_crt_and_wsa(); - ErrorOr open(StringView path, int options, mode_t mode) { ByteString str = path; diff --git a/Libraries/LibMain/Main.cpp b/Libraries/LibMain/Main.cpp index a9cc45ebcb..5410b178fd 100644 --- a/Libraries/LibMain/Main.cpp +++ b/Libraries/LibMain/Main.cpp @@ -10,6 +10,9 @@ #include #include #include +#if defined(AK_OS_WINDOWS) +# include +#endif namespace Main { @@ -31,6 +34,10 @@ int main(int argc, char** argv) { tzset(); +#if defined(AK_OS_WINDOWS) + windows_init(); +#endif + Vector arguments; arguments.ensure_capacity(argc); for (int i = 0; i < argc; ++i) @@ -41,6 +48,11 @@ int main(int argc, char** argv) .argv = argv, .strings = arguments.span(), }); + +#if defined(AK_OS_WINDOWS) + windows_shutdown(); +#endif + if (result.is_error()) { auto error = result.release_error(); warnln("\033[31;1mRuntime error\033[0m: {}", error); diff --git a/Libraries/LibTest/TestMain.cpp b/Libraries/LibTest/TestMain.cpp index 4c95faf0f5..ca9d1ad43a 100644 --- a/Libraries/LibTest/TestMain.cpp +++ b/Libraries/LibTest/TestMain.cpp @@ -8,6 +8,9 @@ #include #include #include +#if defined(AK_OS_WINDOWS) +# include +#endif #define TEST_MAIN main @@ -18,6 +21,10 @@ int TEST_MAIN(int argc, char** argv) return 1; } +#if defined(AK_OS_WINDOWS) + windows_init(); +#endif + Vector arguments; arguments.ensure_capacity(argc); for (auto i = 0; i < argc; ++i) @@ -25,6 +32,9 @@ int TEST_MAIN(int argc, char** argv) int ret = ::Test::TestSuite::the().main(argv[0], arguments); ::Test::TestSuite::release(); +#if defined(AK_OS_WINDOWS) + windows_shutdown(); +#endif // As TestSuite::main() returns the number of test cases that did not pass, // ret can be >=256 which cannot be returned as an exit status directly. // Return 0 if all of the test cases pass and return 1 otherwise.