From 92be54d57a977f3abe7de8f08da3bb3eca452b7b Mon Sep 17 00:00:00 2001 From: Sepalani Date: Wed, 12 Jul 2023 19:18:03 +0400 Subject: [PATCH 1/2] Common/CommonFuncs: Add StrErrorWrapper function --- Source/Core/Common/CommonFuncs.cpp | 38 ++++++++++++++++++------------ Source/Core/Common/CommonFuncs.h | 3 +++ 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/Source/Core/Common/CommonFuncs.cpp b/Source/Core/Common/CommonFuncs.cpp index 4fdefa3a67..a1e93455a2 100644 --- a/Source/Core/Common/CommonFuncs.cpp +++ b/Source/Core/Common/CommonFuncs.cpp @@ -17,27 +17,35 @@ namespace Common { constexpr size_t BUFFER_SIZE = 256; +// There are two variants of strerror_r. The XSI version stores the message to the passed-in +// buffer and returns an int (0 on success). The GNU version returns a pointer to the message, +// which might have been stored in the passed-in buffer or might be a static string. +// +// This function might change the errno value. +// +// References: +// https://www.gnu.org/software/gnulib/manual/html_node/strerror_005fr.html +// https://pubs.opengroup.org/onlinepubs/9699919799/functions/strerror_r.html +// https://refspecs.linuxbase.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/baselib-strerror-r.html +const char* StrErrorWrapper(int error, char* buffer, std::size_t length) +{ + // We check defines in order to figure out which variant is in use. +#if (defined(__GLIBC__) || __ANDROID_API__ >= 23) && \ + (_GNU_SOURCE || (_POSIX_C_SOURCE < 200112L && _XOPEN_SOURCE < 600)) + return strerror_r(error, buffer, length); +#else + const int error_code = strerror_r(error, buffer, length); + return error_code == 0 ? buffer : ""; +#endif +} + // Wrapper function to get last strerror(errno) string. // This function might change the error code. std::string LastStrerrorString() { char error_message[BUFFER_SIZE]; - // There are two variants of strerror_r. The XSI version stores the message to the passed-in - // buffer and returns an int (0 on success). The GNU version returns a pointer to the message, - // which might have been stored in the passed-in buffer or might be a static string. - - // We check defines in order to figure out variant is in use, and we store the returned value - // to a variable so that we'll get a compile-time check that our assumption was correct. - -#if (defined(__GLIBC__) || __ANDROID_API__ >= 23) && \ - (_GNU_SOURCE || (_POSIX_C_SOURCE < 200112L && _XOPEN_SOURCE < 600)) - const char* str = strerror_r(errno, error_message, BUFFER_SIZE); - return std::string(str); -#else - int error_code = strerror_r(errno, error_message, BUFFER_SIZE); - return error_code == 0 ? std::string(error_message) : ""; -#endif + return StrErrorWrapper(errno, error_message, BUFFER_SIZE); } #ifdef _WIN32 diff --git a/Source/Core/Common/CommonFuncs.h b/Source/Core/Common/CommonFuncs.h index cd8dbe94ac..4dac076c04 100644 --- a/Source/Core/Common/CommonFuncs.h +++ b/Source/Core/Common/CommonFuncs.h @@ -41,6 +41,9 @@ __declspec(dllimport) void __stdcall DebugBreak(void); namespace Common { +// strerror_r wrapper to handle XSI and GNU versions. +const char* StrErrorWrapper(int error, char* buffer, std::size_t length); + // Wrapper function to get last strerror(errno) string. // This function might change the error code. std::string LastStrerrorString(); From cbb76c1d4fbccbe08d28a2a26cfe92c507982e43 Mon Sep 17 00:00:00 2001 From: Sepalani Date: Wed, 12 Jul 2023 19:29:35 +0400 Subject: [PATCH 2/2] Common/Network: Use StrErrorWrapper --- Source/Core/Common/Network.cpp | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/Source/Core/Common/Network.cpp b/Source/Core/Common/Network.cpp index a5e56b74d2..f859a8d438 100644 --- a/Source/Core/Common/Network.cpp +++ b/Source/Core/Common/Network.cpp @@ -19,6 +19,7 @@ #include #include "Common/BitUtils.h" +#include "Common/CommonFuncs.h" #include "Common/Random.h" #include "Common/StringUtil.h" @@ -551,23 +552,14 @@ const char* DecodeNetworkError(s32 error_code) { thread_local char buffer[1024]; -#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(ANDROID) || \ - defined(__APPLE__) -#define IS_BSD_STRERROR -#endif - #ifdef _WIN32 FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, nullptr, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, sizeof(buffer), nullptr); return buffer; -#elif defined(IS_BSD_STRERROR) || \ - ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) - strerror_r(error_code, buffer, sizeof(buffer)); - return buffer; #else - return strerror_r(error_code, buffer, sizeof(buffer)); + return Common::StrErrorWrapper(error_code, buffer, sizeof(buffer)); #endif }