1414# include < netinet/tcp.h>
1515# include < signal.h>
1616# include < unistd.h>
17- # include < netinet/tcp.h>
1817#endif
1918
2019namespace clickhouse {
2120
21+ #if defined(_win_)
22+ char const * windowsErrorCategory::name () const noexcept {
23+ return " WindowsSocketError" ;
24+ }
25+
26+ std::string windowsErrorCategory::message (int c) const {
27+ char error[UINT8_MAX];
28+ auto len = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, nullptr , static_cast <DWORD>(c), 0 , error, sizeof (error), nullptr );
29+ if (len == 0 ) {
30+ return " unknown" ;
31+ }
32+ while (len && (error[len - 1 ] == ' \r ' || error[len - 1 ] == ' \n ' )) {
33+ --len;
34+ }
35+ return std::string (error, len);
36+ }
37+
38+ /* static*/ windowsErrorCategory const & windowsErrorCategory::category () {
39+ static windowsErrorCategory c;
40+ return c;
41+ }
42+ #endif
43+
2244namespace {
2345
2446class LocalNames : public std ::unordered_set<std::string> {
@@ -37,6 +59,22 @@ class LocalNames : public std::unordered_set<std::string> {
3759 }
3860};
3961
62+ inline int getSocketErrorCode () {
63+ #if defined(_win_)
64+ return WSAGetLastError ();
65+ #else
66+ return errno;
67+ #endif
68+ }
69+
70+ const std::error_category& getErrorCategory () noexcept {
71+ #if defined(_win_)
72+ return windowsErrorCategory::category ();
73+ #else
74+ return std::system_category ();
75+ #endif
76+ }
77+
4078void SetNonBlock (SOCKET fd, bool value) {
4179#if defined(_unix_)
4280 int flags;
@@ -68,8 +106,7 @@ void SetNonBlock(SOCKET fd, bool value) {
68106 }
69107
70108 if (WSAIoctl (fd, FIONBIO, &inbuf, sizeof (inbuf), &outbuf, sizeof (outbuf), &written, 0 , 0 ) == SOCKET_ERROR) {
71- throw std::system_error (
72- errno, std::system_category (), " fail to set nonblocking mode" );
109+ throw std::system_error (getSocketErrorCode (), getErrorCategory (), " fail to set nonblocking mode" );
73110 }
74111#endif
75112}
@@ -94,16 +131,21 @@ SOCKET SocketConnect(const NetworkAddress& addr) {
94131 SetNonBlock (s, true );
95132
96133 if (connect (s, res->ai_addr , (int )res->ai_addrlen ) != 0 ) {
97- int err = errno;
98- if (err == EINPROGRESS || err == EAGAIN || err == EWOULDBLOCK) {
134+ int err = getSocketErrorCode ();
135+ if (
136+ err == EINPROGRESS || err == EAGAIN || err == EWOULDBLOCK
137+ #if defined(_win_)
138+ || err == WSAEWOULDBLOCK || err == WSAEINPROGRESS
139+ #endif
140+ ) {
99141 pollfd fd;
100142 fd.fd = s;
101143 fd.events = POLLOUT;
102144 fd.revents = 0 ;
103145 ssize_t rval = Poll (&fd, 1 , 5000 );
104146
105147 if (rval == -1 ) {
106- throw std::system_error (errno, std::system_category (), " fail to connect" );
148+ throw std::system_error (getSocketErrorCode (), getErrorCategory (), " fail to connect" );
107149 }
108150 if (rval > 0 ) {
109151 socklen_t len = sizeof (err);
@@ -122,10 +164,9 @@ SOCKET SocketConnect(const NetworkAddress& addr) {
122164 }
123165 }
124166 if (last_err > 0 ) {
125- throw std::system_error (last_err, std::system_category (), " fail to connect" );
167+ throw std::system_error (last_err, getErrorCategory (), " fail to connect" );
126168 }
127- throw std::system_error (
128- errno, std::system_category (), " fail to connect"
169+ throw std::system_error (getSocketErrorCode (), getErrorCategory (), " fail to connect"
129170 );
130171}
131172
0 commit comments