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+ 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;
@@ -55,8 +93,7 @@ void SetNonBlock(SOCKET fd, bool value) {
5593 return ioctl (fd, FIOBIO, &flags);
5694 #endif
5795 if (ret == -1 ) {
58- throw std::system_error (
59- errno, std::system_category (), " fail to set nonblocking mode" );
96+ throw std::system_error (getSocketErrorCode (), getErrorCategory (), " fail to set nonblocking mode" );
6097 }
6198#elif defined(_win_)
6299 unsigned long inbuf = value;
@@ -68,8 +105,7 @@ void SetNonBlock(SOCKET fd, bool value) {
68105 }
69106
70107 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" );
108+ throw std::system_error (getSocketErrorCode (), getErrorCategory (), " fail to set nonblocking mode" );
73109 }
74110#endif
75111}
@@ -94,16 +130,21 @@ SOCKET SocketConnect(const NetworkAddress& addr) {
94130 SetNonBlock (s, true );
95131
96132 if (connect (s, res->ai_addr , (int )res->ai_addrlen ) != 0 ) {
97- int err = errno;
98- if (err == EINPROGRESS || err == EAGAIN || err == EWOULDBLOCK) {
133+ int err = getSocketErrorCode ();
134+ if (
135+ err == EINPROGRESS || err == EAGAIN || err == EWOULDBLOCK
136+ #if defined(_win_)
137+ || err == WSAEWOULDBLOCK || err == WSAEINPROGRESS
138+ #endif
139+ ) {
99140 pollfd fd;
100141 fd.fd = s;
101142 fd.events = POLLOUT;
102143 fd.revents = 0 ;
103144 ssize_t rval = Poll (&fd, 1 , 5000 );
104145
105146 if (rval == -1 ) {
106- throw std::system_error (errno, std::system_category (), " fail to connect" );
147+ throw std::system_error (getSocketErrorCode (), getErrorCategory (), " fail to connect" );
107148 }
108149 if (rval > 0 ) {
109150 socklen_t len = sizeof (err);
@@ -122,11 +163,9 @@ SOCKET SocketConnect(const NetworkAddress& addr) {
122163 }
123164 }
124165 if (last_err > 0 ) {
125- throw std::system_error (last_err, std::system_category (), " fail to connect" );
166+ throw std::system_error (last_err, getErrorCategory (), " fail to connect" );
126167 }
127- throw std::system_error (
128- errno, std::system_category (), " fail to connect"
129- );
168+ throw std::system_error (getSocketErrorCode (), getErrorCategory (), " fail to connect" );
130169}
131170
132171} // namespace
@@ -156,7 +195,7 @@ NetworkAddress::NetworkAddress(const std::string& host, const std::string& port)
156195 const int error = getaddrinfo (host.c_str (), port.c_str (), &hints, &info_);
157196
158197 if (error) {
159- throw std::system_error (errno, std::system_category ());
198+ throw std::system_error (getSocketErrorCode (), getErrorCategory ());
160199 }
161200}
162201
@@ -262,14 +301,10 @@ size_t SocketInput::DoRead(void* buf, size_t len) {
262301 }
263302
264303 if (ret == 0 ) {
265- throw std::system_error (
266- errno, std::system_category (), " closed"
267- );
304+ throw std::system_error (getSocketErrorCode (), getErrorCategory (), " closed" );
268305 }
269306
270- throw std::system_error (
271- errno, std::system_category (), " can't receive string data"
272- );
307+ throw std::system_error (getSocketErrorCode (), getErrorCategory (), " can't receive string data" );
273308}
274309
275310bool SocketInput::Skip (size_t /* bytes*/ ) {
@@ -292,9 +327,7 @@ size_t SocketOutput::DoWrite(const void* data, size_t len) {
292327#endif
293328
294329 if (::send (s_, (const char *)data, (int )len, flags) != (int )len) {
295- throw std::system_error (
296- errno, std::system_category (), " fail to send " + std::to_string (len) + " bytes of data"
297- );
330+ throw std::system_error (getSocketErrorCode (), getErrorCategory (), " fail to send " + std::to_string (len) + " bytes of data" );
298331 }
299332
300333 return len;
0 commit comments