|
28 | 28 | #include <log4cplus/internal/socket.h>
|
29 | 29 | #include <log4cplus/helpers/loglog.h>
|
30 | 30 | #include <log4cplus/thread/threads.h>
|
| 31 | +#include <log4cplus/helpers/stringhelper.h> |
31 | 32 |
|
32 | 33 |
|
33 | 34 | /////////////////////////////////////////////////////////////////////////////
|
@@ -261,12 +262,68 @@ acceptSocket(SOCKET_TYPE sock, SocketState & state)
|
261 | 262 | {
|
262 | 263 | init_winsock ();
|
263 | 264 |
|
264 |
| - SOCKET connected_socket = ::accept (to_os_socket (sock), NULL, NULL); |
| 265 | + SOCKET osSocket = to_os_socket (sock); |
265 | 266 |
|
266 |
| - if (connected_socket != INVALID_OS_SOCKET_VALUE) |
267 |
| - state = ok; |
| 267 | + // Check that the socket is ok. |
268 | 268 |
|
269 |
| - return to_log4cplus_socket (connected_socket); |
| 269 | + int val = 0; |
| 270 | + int optlen = sizeof (val); |
| 271 | + int ret = getsockopt (osSocket, SOL_SOCKET, SO_TYPE, |
| 272 | + reinterpret_cast<char *>(&val), &optlen); |
| 273 | + if (ret == SOCKET_ERROR) |
| 274 | + goto error; |
| 275 | + |
| 276 | + // Now that we know the socket is working ok we can wait for |
| 277 | + // either a new connection or for a transition to bad state. |
| 278 | + |
| 279 | + while (1) |
| 280 | + { |
| 281 | + fd_set readSet; |
| 282 | + timeval timeout; |
| 283 | + |
| 284 | + FD_ZERO (&readSet); |
| 285 | + FD_SET (osSocket, &readSet); |
| 286 | + timeout.tv_sec = 0; |
| 287 | + timeout.tv_usec = 200 * 1000; |
| 288 | + |
| 289 | + int selectResponse = ::select (1, &readSet, NULL, NULL, &timeout); |
| 290 | + if (selectResponse < 0) |
| 291 | + { |
| 292 | + DWORD const eno = WSAGetLastError (); |
| 293 | + if (eno == WSAENOTSOCK || eno == WSAEINVAL) |
| 294 | + WSASetLastError (ERROR_NO_DATA); |
| 295 | + |
| 296 | + goto error; |
| 297 | + } |
| 298 | + else if (selectResponse == 0) |
| 299 | + // Timeout. |
| 300 | + continue; |
| 301 | + else if (selectResponse == 1) |
| 302 | + { |
| 303 | + SOCKET connected_socket = ::accept (osSocket, NULL, NULL); |
| 304 | + |
| 305 | + if (connected_socket != INVALID_OS_SOCKET_VALUE) |
| 306 | + state = ok; |
| 307 | + else |
| 308 | + goto error; |
| 309 | + |
| 310 | + return to_log4cplus_socket (connected_socket); |
| 311 | + } |
| 312 | + else |
| 313 | + { |
| 314 | + helpers::getLogLog ().error ( |
| 315 | + LOG4CPLUS_TEXT ("unexpected select() return value: ") |
| 316 | + + helpers::convertIntegerToString (selectResponse)); |
| 317 | + WSASetLastError (ERROR_UNSUPPORTED_TYPE); |
| 318 | + goto error; |
| 319 | + } |
| 320 | + } |
| 321 | + |
| 322 | +error: |
| 323 | + DWORD eno = WSAGetLastError (); |
| 324 | + set_last_socket_error (eno); |
| 325 | + |
| 326 | + return to_log4cplus_socket (INVALID_SOCKET); |
270 | 327 | }
|
271 | 328 |
|
272 | 329 |
|
|
0 commit comments