diff options
author | Devtools Arcadia <[email protected]> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <[email protected]> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /util/system/error.cpp |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'util/system/error.cpp')
-rw-r--r-- | util/system/error.cpp | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/util/system/error.cpp b/util/system/error.cpp new file mode 100644 index 00000000000..f778ec42cbe --- /dev/null +++ b/util/system/error.cpp @@ -0,0 +1,96 @@ +#include "tls.h" +#include "error.h" + +#include <util/string/strip.h> +#include <util/generic/strfcpy.h> + +#include <cerrno> +#include <cstdio> +#include <cstring> + +#if defined(_win_) + #include <util/network/socket.h> + #include <util/generic/singleton.h> + #include "winint.h" +#elif defined(_unix_) + #include <unistd.h> +#endif + +void ClearLastSystemError() { +#if defined(_win_) + SetLastError(0); +#else + errno = 0; +#endif +} + +int LastSystemError() { +#if defined(_win_) + int ret = GetLastError(); + + if (ret) + return ret; + + ret = WSAGetLastError(); + + if (ret) + return ret; + // when descriptors number are over maximum, errno set in this variable + ret = *(_errno()); + return ret; + +#else + return errno; +#endif +} + +#if defined(_win_) +namespace { + struct TErrString { + inline TErrString() noexcept { + data[0] = 0; + } + + char data[1024]; + }; +} +#endif + +const char* LastSystemErrorText(int code) { +#if defined(_win_) + TErrString& text(*Singleton<TErrString>()); + LastSystemErrorText(text.data, sizeof(text.data), code); + + return text.data; +#else + return strerror(code); +#endif +} + +#ifdef _win_ +static char* Strip(char* s) { + size_t len = strlen(s); + const char* ptr = s; + Strip(ptr, len); + if (ptr != s) + memmove(s, ptr, len); + s[len] = 0; + return s; +} +#endif // _win_ + +void LastSystemErrorText(char* str, size_t size, int code) { +#if defined(_win_) + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, code, 0, str, DWORD(size), 0); + Strip(str); +#elif defined(_sun_) + strfcpy(str, strerror(code), size); +#elif defined(_freebsd_) || defined(_darwin_) || defined(_musl_) || defined(_bionic_) + strerror_r(code, str, size); +#elif defined(_linux_) | defined(_cygwin_) + char* msg = strerror_r(code, str, size); + strncpy(str, msg, size); +#else + #error port me gently! +#endif +} |