diff options
| author | JosJuice <josjuice@gmail.com> | 2017-12-16 13:08:50 +0100 |
|---|---|---|
| committer | JosJuice <josjuice@gmail.com> | 2017-12-18 22:09:02 +0100 |
| commit | bd5da5cfd60d2d2321579800ed62471a4a663e88 (patch) | |
| tree | 8e04fe4a43badfb244829bf6ab587e9d8349a924 /Source/Core/Common/CommonFuncs.cpp | |
| parent | ba01642dc78a44126b334d7ff4d3ceae5fec7902 (diff) | |
Handle both the XSI and GNU versions of strerror_r
Trying to force the XSI version by undefining _GNU_SOURCE can lead
to compilation errors on some systems because of headers expecting
that _GNU_SOURCE is defined.
This commit uses define checks to detect which version we have.
I tried making an overloaded function (int and const char*) instead,
but that led to a warning about one of the variants being unused.
Diffstat (limited to 'Source/Core/Common/CommonFuncs.cpp')
| -rw-r--r-- | Source/Core/Common/CommonFuncs.cpp | 36 |
1 files changed, 16 insertions, 20 deletions
diff --git a/Source/Core/Common/CommonFuncs.cpp b/Source/Core/Common/CommonFuncs.cpp index ef370672d2..86b9c93e40 100644 --- a/Source/Core/Common/CommonFuncs.cpp +++ b/Source/Core/Common/CommonFuncs.cpp @@ -2,21 +2,10 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. -// The code in GetErrorMessage can't handle some systems having the -// GNU version of strerror_r and other systems having the XSI version, -// so we undefine _GNU_SOURCE here in an attempt to always get the XSI version. -// We include cstring before all other headers in case cstring is included -// indirectly (without undefining _GNU_SOURCE) by some other header. -#ifdef _GNU_SOURCE -#undef _GNU_SOURCE -#include <cstring> -#define _GNU_SOURCE -#else -#include <cstring> -#endif - #include <cstddef> +#include <cstring> #include <errno.h> +#include <type_traits> #include "Common/CommonFuncs.h" @@ -33,13 +22,20 @@ std::string LastStrerrorString() { char error_message[BUFFER_SIZE]; - // We assume that the XSI-compliant version of strerror_r (returns int) is used - // rather than the GNU version (returns char*). The returned value is stored to - // an int variable to get a compile-time check that the return type is not char*. - const int result = strerror_r(errno, error_message, BUFFER_SIZE); - if (result != 0) - return ""; - return std::string(error_message); +// 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__) && (_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 } #ifdef _WIN32 |
