| 2445 | } |
| 2446 | |
| 2447 | inline Error wait_until_socket_is_ready(socket_t sock, time_t sec, |
| 2448 | time_t usec) { |
| 2449 | #ifdef CPPHTTPLIB_USE_POLL |
| 2450 | struct pollfd pfd_read; |
| 2451 | pfd_read.fd = sock; |
| 2452 | pfd_read.events = POLLIN | POLLOUT; |
| 2453 | |
| 2454 | auto timeout = static_cast<int>(sec * 1000 + usec / 1000); |
| 2455 | |
| 2456 | auto poll_res = handle_EINTR([&]() { return poll(&pfd_read, 1, timeout); }); |
| 2457 | |
| 2458 | if (poll_res == 0) { return Error::ConnectionTimeout; } |
| 2459 | |
| 2460 | if (poll_res > 0 && pfd_read.revents & (POLLIN | POLLOUT)) { |
| 2461 | int error = 0; |
| 2462 | socklen_t len = sizeof(error); |
| 2463 | auto res = getsockopt(sock, SOL_SOCKET, SO_ERROR, |
| 2464 | reinterpret_cast<char *>(&error), &len); |
| 2465 | auto successful = res >= 0 && !error; |
| 2466 | return successful ? Error::Success : Error::Connection; |
| 2467 | } |
| 2468 | |
| 2469 | return Error::Connection; |
| 2470 | #else |
| 2471 | #ifndef _WIN32 |
| 2472 | if (sock >= FD_SETSIZE) { return Error::Connection; } |
| 2473 | #endif |
| 2474 | |
| 2475 | fd_set fdsr; |
| 2476 | FD_ZERO(&fdsr); |
| 2477 | FD_SET(sock, &fdsr); |
| 2478 | |
| 2479 | auto fdsw = fdsr; |
| 2480 | auto fdse = fdsr; |
| 2481 | |
| 2482 | timeval tv; |
| 2483 | tv.tv_sec = static_cast<long>(sec); |
| 2484 | tv.tv_usec = static_cast<decltype(tv.tv_usec)>(usec); |
| 2485 | |
| 2486 | auto ret = handle_EINTR([&]() { |
| 2487 | return select(static_cast<int>(sock + 1), &fdsr, &fdsw, &fdse, &tv); |
| 2488 | }); |
| 2489 | |
| 2490 | if (ret == 0) { return Error::ConnectionTimeout; } |
| 2491 | |
| 2492 | if (ret > 0 && (FD_ISSET(sock, &fdsr) || FD_ISSET(sock, &fdsw))) { |
| 2493 | int error = 0; |
| 2494 | socklen_t len = sizeof(error); |
| 2495 | auto res = getsockopt(sock, SOL_SOCKET, SO_ERROR, |
| 2496 | reinterpret_cast<char *>(&error), &len); |
| 2497 | auto successful = res >= 0 && !error; |
| 2498 | return successful ? Error::Success : Error::Connection; |
| 2499 | } |
| 2500 | return Error::Connection; |
| 2501 | #endif |
| 2502 | } |
| 2503 | |
| 2504 | inline bool is_socket_alive(socket_t sock) { |
no test coverage detected