aboutsummaryrefslogtreecommitdiffstats
path: root/util/system/error.cpp
blob: 6ba2dc64b53bafbdb4a138c3a843495dab3f7ed6 (plain) (blame)
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
93
94
95
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 
}