| 2323 | } |
| 2324 | |
| 2325 | inline Error wait_until_socket_is_ready(socket_t sock, time_t sec, |
| 2326 | time_t usec) { |
| 2327 | #ifdef CPPHTTPLIB_USE_POLL |
| 2328 | struct pollfd pfd_read; |
| 2329 | pfd_read.fd = sock; |
| 2330 | pfd_read.events = POLLIN | POLLOUT; |
| 2331 | |
| 2332 | auto timeout = static_cast<int>(sec * 1000 + usec / 1000); |
| 2333 | |
| 2334 | auto poll_res = handle_EINTR([&]() { return poll(&pfd_read, 1, timeout); }); |
| 2335 | |
| 2336 | if (poll_res == 0) { return Error::ConnectionTimeout; } |
| 2337 | |
| 2338 | if (poll_res > 0 && pfd_read.revents & (POLLIN | POLLOUT)) { |
| 2339 | int error = 0; |
| 2340 | socklen_t len = sizeof(error); |
| 2341 | auto res = getsockopt(sock, SOL_SOCKET, SO_ERROR, |
| 2342 | reinterpret_cast<char *>(&error), &len); |
| 2343 | auto successful = res >= 0 && !error; |
| 2344 | return successful ? Error::Success : Error::Connection; |
| 2345 | } |
| 2346 | |
| 2347 | return Error::Connection; |
| 2348 | #else |
| 2349 | #ifndef _WIN32 |
| 2350 | if (sock >= FD_SETSIZE) { return Error::Connection; } |
| 2351 | #endif |
| 2352 | |
| 2353 | fd_set fdsr; |
| 2354 | FD_ZERO(&fdsr); |
| 2355 | FD_SET(sock, &fdsr); |
| 2356 | |
| 2357 | auto fdsw = fdsr; |
| 2358 | auto fdse = fdsr; |
| 2359 | |
| 2360 | timeval tv; |
| 2361 | tv.tv_sec = static_cast<long>(sec); |
| 2362 | tv.tv_usec = static_cast<decltype(tv.tv_usec)>(usec); |
| 2363 | |
| 2364 | auto ret = handle_EINTR([&]() { |
| 2365 | return select(static_cast<int>(sock + 1), &fdsr, &fdsw, &fdse, &tv); |
| 2366 | }); |
| 2367 | |
| 2368 | if (ret == 0) { return Error::ConnectionTimeout; } |
| 2369 | |
| 2370 | if (ret > 0 && (FD_ISSET(sock, &fdsr) || FD_ISSET(sock, &fdsw))) { |
| 2371 | int error = 0; |
| 2372 | socklen_t len = sizeof(error); |
| 2373 | auto res = getsockopt(sock, SOL_SOCKET, SO_ERROR, |
| 2374 | reinterpret_cast<char *>(&error), &len); |
| 2375 | auto successful = res >= 0 && !error; |
| 2376 | return successful ? Error::Success : Error::Connection; |
| 2377 | } |
| 2378 | return Error::Connection; |
| 2379 | #endif |
| 2380 | } |
| 2381 | |
| 2382 | inline bool is_socket_alive(socket_t sock) { |
no test coverage detected