-
Notifications
You must be signed in to change notification settings - Fork 186
Closed
Description
When i was building Havoc Framework which imports toml11 on my m1 mac, I got error like
error stack
In file included from /tmp/Havoc/client/src/Havoc/PythonApi/UI/PyLoggerClass.cc:6:
In file included from /tmp/Havoc/client/include/Havoc/PythonApi/PythonApi.h:4:
In file included from /tmp/Havoc/client/include/global.hpp:36:
In file included from /tmp/Havoc/client/include/External.h:6:
In file included from /tmp/Havoc/client/external/toml/toml.hpp:32:
In file included from /tmp/Havoc/client/external/toml/toml/parser.hpp:14:
In file included from /tmp/Havoc/client/external/toml/toml/value.hpp:8:
/tmp/Havoc/client/external/toml/toml/exception.hpp:44:17: error: cannot initialize a variable of type 'const char *' with an rvalue of type 'int'
const char* result = strerror_r(errnum, buf.data(), bufsize);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning and 1 error generated.
Then I found this project and found different process here.
# ./toml/exception.hpp
inline std::string str_error(int errnum)
{
// C++ standard strerror is not thread-safe.
// C11 provides thread-safe version of this function, `strerror_s`, but it
// is not available in C++.
// To avoid using std::strerror, we need to use platform-specific functions.
// If none of the conditions are met, it calls std::strerror as a fallback.
#ifdef _MSC_VER // MSVC
constexpr std::size_t bufsize = 256;
std::array<char, bufsize> buf;
buf.fill('\0');
const auto result = strerror_s(buf.data(), bufsize, errnum); # here use auto
if(result != 0)
{
return std::string("strerror_s failed");
}
else
{
return std::string(buf.data());
}
#elif defined(_GNU_SOURCE)
constexpr std::size_t bufsize = 256;
std::array<char, bufsize> buf;
buf.fill('\0');
const char* result = strerror_r(errnum, buf.data(), bufsize); # here receive as const char*
return std::string(result);
#elif (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600)
constexpr std::size_t bufsize = 256;
std::array<char, bufsize> buf;
buf.fill('\0');
const int result = strerror_r(errnum, buf.data(), bufsize); # but here is int
if (result != 0)
{
return std::string("strerror_r failed");
}
else
{
return std::string(buf.data());
}
#else // fallback
return std::strerror(errnum);
#endifbut my macos c header looks like
# /Library/Developer/CommandLineTools/SDKs/MacOSX13.3.sdk/usr/include/string.h
/* Additional functionality provided by:
* POSIX.1-2001
*/
#if __DARWIN_C_LEVEL >= 200112L
__BEGIN_DECLS
int strerror_r(int __errnum, char *__strerrbuf, size_t __buflen);
char *strdup(const char *__s1);
void *memccpy(void *__dst, const void *__src, int __c, size_t __n);
__END_DECLS
#endif /* __DARWIN_C_LEVEL >= 200112L */current fix
I changed the code like following to patch a little but it's not good I think.
inline std::string str_error(int errnum) {
// C++ standard strerror is not thread-safe.
// C11 provides thread-safe version of this function, `strerror_s`, but it
// is not available in C++.
// To avoid using std::strerror, we need to use platform-specific functions.
// If none of the conditions are met, it calls std::strerror as a fallback.
#ifdef _MSC_VER // MSVC
constexpr std::size_t bufsize = 256;
std::array<char, bufsize> buf;
buf.fill('\0');
const auto result = strerror_s(buf.data(), bufsize, errnum);
if (result != 0) {
return std::string("strerror_s failed");
} else {
return std::string(buf.data());
}
#elif defined(_GNU_SOURCE)
constexpr std::size_t bufsize = 256;
std::array<char, bufsize> buf;
buf.fill('\0');
const int result = strerror_r(errnum, buf.data(), bufsize);
if (result != 0) {
return std::string("strerror_r failed");
} else {
return std::string(buf.data());
}
#elif (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || \
(defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600)
constexpr std::size_t bufsize = 256;
std::array<char, bufsize> buf;
buf.fill('\0');
const int result = strerror_r(errnum, buf.data(), bufsize);
if (result != 0) {
return std::string("strerror_r failed");
} else {
return std::string(buf.data());
}
#else // fallback
return std::strerror(errnum);
#endif
}
It looks like to following the (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 600) condition and compile the code.
Is it a bug or need more classification in macro?
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels