1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
#include "error.h"
#include <util/generic/strfcpy.h>
#include <cerrno>
#include <cstring>
#if defined(_win_)
#include <util/string/strip.h>
#include <util/network/socket.h>
#include <util/generic/singleton.h>
#include "winint.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];
};
} // namespace
#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_) || defined(_emscripten_)
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
}
|