summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorAdmiral H. Curtiss <pikachu025@gmail.com>2023-07-16 19:46:00 +0200
committerGitHub <noreply@github.com>2023-07-16 19:46:00 +0200
commitd867e2baeb95f6fddd7aee2679d5c324a1c5bd1d (patch)
tree641e9fc4687534e8a5116b3c149849ebf9b1c862 /Source/Core
parent7f40c6f2f86cb3f77b155240df0e512dfe1eef29 (diff)
parentcbb76c1d4fbccbe08d28a2a26cfe92c507982e43 (diff)
Merge pull request #12043 from sepalani/strerror
Common: Add a strerror_r wrapper
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Common/CommonFuncs.cpp38
-rw-r--r--Source/Core/Common/CommonFuncs.h3
-rw-r--r--Source/Core/Common/Network.cpp12
3 files changed, 28 insertions, 25 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();
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 <fmt/format.h>
#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
}