@@ -3202,13 +3202,31 @@ inline int poll_wrapper(struct pollfd *fds, nfds_t nfds, int timeout) {
3202
3202
3203
3203
template <bool Read>
3204
3204
inline ssize_t select_impl (socket_t sock, time_t sec, time_t usec) {
3205
+ #ifdef __APPLE__
3206
+ if (sock >= FD_SETSIZE) { return -1 ; }
3207
+
3208
+ fd_set fds, *rfds, *wfds;
3209
+ FD_ZERO (&fds);
3210
+ FD_SET (sock, &fds);
3211
+ rfds = (Read ? &fds : nullptr );
3212
+ wfds = (Read ? nullptr : &fds);
3213
+
3214
+ timeval tv;
3215
+ tv.tv_sec = static_cast <long >(sec);
3216
+ tv.tv_usec = static_cast <decltype (tv.tv_usec )>(usec);
3217
+
3218
+ return handle_EINTR ([&]() {
3219
+ return select (static_cast <int >(sock + 1 ), rfds, wfds, nullptr , &tv);
3220
+ });
3221
+ #else
3205
3222
struct pollfd pfd;
3206
3223
pfd.fd = sock;
3207
3224
pfd.events = (Read ? POLLIN : POLLOUT);
3208
3225
3209
3226
auto timeout = static_cast <int >(sec * 1000 + usec / 1000 );
3210
3227
3211
3228
return handle_EINTR ([&]() { return poll_wrapper (&pfd, 1 , timeout); });
3229
+ #endif
3212
3230
}
3213
3231
3214
3232
inline ssize_t select_read (socket_t sock, time_t sec, time_t usec) {
@@ -3221,6 +3239,36 @@ inline ssize_t select_write(socket_t sock, time_t sec, time_t usec) {
3221
3239
3222
3240
inline Error wait_until_socket_is_ready (socket_t sock, time_t sec,
3223
3241
time_t usec) {
3242
+ #ifdef __APPLE__
3243
+ if (sock >= FD_SETSIZE) { return Error::Connection; }
3244
+
3245
+ fd_set fdsr, fdsw;
3246
+ FD_ZERO (&fdsr);
3247
+ FD_ZERO (&fdsw);
3248
+ FD_SET (sock, &fdsr);
3249
+ FD_SET (sock, &fdsw);
3250
+
3251
+ timeval tv;
3252
+ tv.tv_sec = static_cast <long >(sec);
3253
+ tv.tv_usec = static_cast <decltype (tv.tv_usec )>(usec);
3254
+
3255
+ auto ret = handle_EINTR ([&]() {
3256
+ return select (static_cast <int >(sock + 1 ), &fdsr, &fdsw, nullptr , &tv);
3257
+ });
3258
+
3259
+ if (ret == 0 ) { return Error::ConnectionTimeout; }
3260
+
3261
+ if (ret > 0 && (FD_ISSET (sock, &fdsr) || FD_ISSET (sock, &fdsw))) {
3262
+ auto error = 0 ;
3263
+ socklen_t len = sizeof (error);
3264
+ auto res = getsockopt (sock, SOL_SOCKET, SO_ERROR,
3265
+ reinterpret_cast <char *>(&error), &len);
3266
+ auto successful = res >= 0 && !error;
3267
+ return successful ? Error::Success : Error::Connection;
3268
+ }
3269
+
3270
+ return Error::Connection;
3271
+ #else
3224
3272
struct pollfd pfd_read;
3225
3273
pfd_read.fd = sock;
3226
3274
pfd_read.events = POLLIN | POLLOUT;
@@ -3242,6 +3290,7 @@ inline Error wait_until_socket_is_ready(socket_t sock, time_t sec,
3242
3290
}
3243
3291
3244
3292
return Error::Connection;
3293
+ #endif
3245
3294
}
3246
3295
3247
3296
inline bool is_socket_alive (socket_t sock) {
@@ -7916,6 +7965,16 @@ Server::process_request(Stream &strm, const std::string &remote_addr,
7916
7965
res.version = " HTTP/1.1" ;
7917
7966
res.headers = default_headers_;
7918
7967
7968
+ #ifdef __APPLE__
7969
+ // Socket file descriptor exceeded FD_SETSIZE...
7970
+ if (strm.socket () >= FD_SETSIZE) {
7971
+ Headers dummy;
7972
+ detail::read_headers (strm, dummy);
7973
+ res.status = StatusCode::InternalServerError_500;
7974
+ return write_response (strm, close_connection, req, res);
7975
+ }
7976
+ #endif
7977
+
7919
7978
// Request line and headers
7920
7979
if (!parse_request_line (line_reader.ptr (), req) ||
7921
7980
!detail::read_headers (strm, req.headers )) {
0 commit comments