error.cpp 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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. }
  24. ret = WSAGetLastError();
  25. if (ret) {
  26. return ret;
  27. }
  28. // when descriptors number are over maximum, errno set in this variable
  29. ret = *(_errno());
  30. return ret;
  31. #else
  32. return errno;
  33. #endif
  34. }
  35. #if defined(_win_)
  36. namespace {
  37. struct TErrString {
  38. inline TErrString() noexcept {
  39. data[0] = 0;
  40. }
  41. char data[1024];
  42. };
  43. } // namespace
  44. #endif
  45. const char* LastSystemErrorText(int code) {
  46. #if defined(_win_)
  47. TErrString& text(*Singleton<TErrString>());
  48. LastSystemErrorText(text.data, sizeof(text.data), code);
  49. return text.data;
  50. #else
  51. return strerror(code);
  52. #endif
  53. }
  54. #ifdef _win_
  55. static char* Strip(char* s) {
  56. size_t len = strlen(s);
  57. const char* ptr = s;
  58. Strip(ptr, len);
  59. if (ptr != s) {
  60. memmove(s, ptr, len);
  61. }
  62. s[len] = 0;
  63. return s;
  64. }
  65. #endif // _win_
  66. void LastSystemErrorText(char* str, size_t size, int code) {
  67. #if defined(_win_)
  68. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, code, 0, str, DWORD(size), 0);
  69. Strip(str);
  70. #elif defined(_sun_)
  71. strfcpy(str, strerror(code), size);
  72. #elif defined(_freebsd_) || defined(_darwin_) || defined(_musl_) || defined(_bionic_) || defined(_emscripten_)
  73. strerror_r(code, str, size);
  74. #elif defined(_linux_) | defined(_cygwin_)
  75. char* msg = strerror_r(code, str, size);
  76. strncpy(str, msg, size);
  77. #else
  78. #error port me gently!
  79. #endif
  80. }