@@ -3218,13 +3218,31 @@ inline int poll_wrapper(struct pollfd *fds, nfds_t nfds, int timeout) {
3218
3218
3219
3219
template <bool Read>
3220
3220
inline ssize_t select_impl (socket_t sock, time_t sec, time_t usec) {
3221
+ #ifdef __APPLE__
3222
+ if (sock >= FD_SETSIZE) { return -1 ; }
3223
+
3224
+ fd_set fds, *rfds, *wfds;
3225
+ FD_ZERO (&fds);
3226
+ FD_SET (sock, &fds);
3227
+ rfds = (Read ? &fds : nullptr );
3228
+ wfds = (Read ? nullptr : &fds);
3229
+
3230
+ timeval tv;
3231
+ tv.tv_sec = static_cast <long >(sec);
3232
+ tv.tv_usec = static_cast <decltype (tv.tv_usec )>(usec);
3233
+
3234
+ return handle_EINTR ([&]() {
3235
+ return select (static_cast <int >(sock + 1 ), rfds, wfds, nullptr , &tv);
3236
+ });
3237
+ #else
3221
3238
struct pollfd pfd;
3222
3239
pfd.fd = sock;
3223
3240
pfd.events = (Read ? POLLIN : POLLOUT);
3224
3241
3225
3242
auto timeout = static_cast <int >(sec * 1000 + usec / 1000 );
3226
3243
3227
3244
return handle_EINTR ([&]() { return poll_wrapper (&pfd, 1 , timeout); });
3245
+ #endif
3228
3246
}
3229
3247
3230
3248
inline ssize_t select_read (socket_t sock, time_t sec, time_t usec) {
@@ -3237,6 +3255,36 @@ inline ssize_t select_write(socket_t sock, time_t sec, time_t usec) {
3237
3255
3238
3256
inline Error wait_until_socket_is_ready (socket_t sock, time_t sec,
3239
3257
time_t usec) {
3258
+ #ifdef __APPLE__
3259
+ if (sock >= FD_SETSIZE) { return Error::Connection; }
3260
+
3261
+ fd_set fdsr, fdsw;
3262
+ FD_ZERO (&fdsr);
3263
+ FD_ZERO (&fdsw);
3264
+ FD_SET (sock, &fdsr);
3265
+ FD_SET (sock, &fdsw);
3266
+
3267
+ timeval tv;
3268
+ tv.tv_sec = static_cast <long >(sec);
3269
+ tv.tv_usec = static_cast <decltype (tv.tv_usec )>(usec);
3270
+
3271
+ auto ret = handle_EINTR ([&]() {
3272
+ return select (static_cast <int >(sock + 1 ), &fdsr, &fdsw, nullptr , &tv);
3273
+ });
3274
+
3275
+ if (ret == 0 ) { return Error::ConnectionTimeout; }
3276
+
3277
+ if (ret > 0 && (FD_ISSET (sock, &fdsr) || FD_ISSET (sock, &fdsw))) {
3278
+ auto error = 0 ;
3279
+ socklen_t len = sizeof (error);
3280
+ auto res = getsockopt (sock, SOL_SOCKET, SO_ERROR,
3281
+ reinterpret_cast <char *>(&error), &len);
3282
+ auto successful = res >= 0 && !error;
3283
+ return successful ? Error::Success : Error::Connection;
3284
+ }
3285
+
3286
+ return Error::Connection;
3287
+ #else
3240
3288
struct pollfd pfd_read;
3241
3289
pfd_read.fd = sock;
3242
3290
pfd_read.events = POLLIN | POLLOUT;
@@ -3258,6 +3306,7 @@ inline Error wait_until_socket_is_ready(socket_t sock, time_t sec,
3258
3306
}
3259
3307
3260
3308
return Error::Connection;
3309
+ #endif
3261
3310
}
3262
3311
3263
3312
inline bool is_socket_alive (socket_t sock) {
@@ -7894,6 +7943,16 @@ Server::process_request(Stream &strm, const std::string &remote_addr,
7894
7943
res.version = " HTTP/1.1" ;
7895
7944
res.headers = default_headers_;
7896
7945
7946
+ #ifdef __APPLE__
7947
+ // Socket file descriptor exceeded FD_SETSIZE...
7948
+ if (strm.socket () >= FD_SETSIZE) {
7949
+ Headers dummy;
7950
+ detail::read_headers (strm, dummy);
7951
+ res.status = StatusCode::InternalServerError_500;
7952
+ return write_response (strm, close_connection, req, res, Error::Read);
7953
+ }
7954
+ #endif
7955
+
7897
7956
// Request line and headers
7898
7957
if (!parse_request_line (line_reader.ptr (), req) ||
7899
7958
!detail::read_headers (strm, req.headers )) {
0 commit comments