error.cpp 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #include "error.h"
  2. #include <util/generic/strfcpy.h>
  3. #include <cerrno>
  4. #include <cstring>
  5. #if defined(_win_)
  6. #include <util/string/strip.h>
  7. #include <util/network/socket.h>
  8. #include <util/generic/singleton.h>
  9. #include "winint.h"
  10. #endif
  11. void ClearLastSystemError() {
  12. #if defined(_win_)
  13. SetLastError(0);
  14. #else
  15. errno = 0;
  16. #endif
  17. }
  18. int LastSystemError() {
  19. #if defined(_win_)
  20. int ret = GetLastError();
  21. if (ret)
  22. return ret;
  23. ret = WSAGetLastError();
  24. if (ret)
  25. return ret;
  26. // when descriptors number are over maximum, errno set in this variable
  27. ret = *(_errno());
  28. return ret;
  29. #else
  30. return errno;
  31. #endif
  32. }
  33. #if defined(_win_)
  34. namespace {
  35. struct TErrString {
  36. inline TErrString() noexcept {
  37. data[0] = 0;
  38. }
  39. char data[1024];
  40. };
  41. } // namespace
  42. #endif
  43. const char* LastSystemErrorText(int code) {
  44. #if defined(_win_)
  45. TErrString& text(*Singleton<TErrString>());
  46. LastSystemErrorText(text.data, sizeof(text.data), code);
  47. return text.data;
  48. #else
  49. return strerror(code);
  50. #endif
  51. }
  52. #ifdef _win_
  53. static char* Strip(char* s) {
  54. size_t len = strlen(s);
  55. const char* ptr = s;
  56. Strip(ptr, len);
  57. if (ptr != s)
  58. memmove(s, ptr, len);
  59. s[len] = 0;
  60. return s;
  61. }
  62. #endif // _win_
  63. void LastSystemErrorText(char* str, size_t size, int code) {
  64. #if defined(_win_)
  65. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, code, 0, str, DWORD(size), 0);
  66. Strip(str);
  67. #elif defined(_sun_)
  68. strfcpy(str, strerror(code), size);
  69. #elif defined(_freebsd_) || defined(_darwin_) || defined(_musl_) || defined(_bionic_) || defined(_emscripten_)
  70. strerror_r(code, str, size);
  71. #elif defined(_linux_) | defined(_cygwin_)
  72. char* msg = strerror_r(code, str, size);
  73. strncpy(str, msg, size);
  74. #else
  75. #error port me gently!
  76. #endif
  77. }