@@ -3215,13 +3215,31 @@ inline int poll_wrapper(struct pollfd *fds, nfds_t nfds, int timeout) {
3215
3215
3216
3216
template <bool Read>
3217
3217
inline ssize_t select_impl (socket_t sock, time_t sec, time_t usec) {
3218
+ #ifdef __APPLE__
3219
+ if (sock >= FD_SETSIZE) { return -1 ; }
3220
+
3221
+ fd_set fds, *rfds, *wfds;
3222
+ FD_ZERO (&fds);
3223
+ FD_SET (sock, &fds);
3224
+ rfds = (Read ? &fds : nullptr );
3225
+ wfds = (Read ? nullptr : &fds);
3226
+
3227
+ timeval tv;
3228
+ tv.tv_sec = static_cast <long >(sec);
3229
+ tv.tv_usec = static_cast <decltype (tv.tv_usec )>(usec);
3230
+
3231
+ return handle_EINTR ([&]() {
3232
+ return select (static_cast <int >(sock + 1 ), rfds, wfds, nullptr , &tv);
3233
+ });
3234
+ #else
3218
3235
struct pollfd pfd;
3219
3236
pfd.fd = sock;
3220
3237
pfd.events = (Read ? POLLIN : POLLOUT);
3221
3238
3222
3239
auto timeout = static_cast <int >(sec * 1000 + usec / 1000 );
3223
3240
3224
3241
return handle_EINTR ([&]() { return poll_wrapper (&pfd, 1 , timeout); });
3242
+ #endif
3225
3243
}
3226
3244
3227
3245
inline ssize_t select_read (socket_t sock, time_t sec, time_t usec) {
@@ -3234,6 +3252,36 @@ inline ssize_t select_write(socket_t sock, time_t sec, time_t usec) {
3234
3252
3235
3253
inline Error wait_until_socket_is_ready (socket_t sock, time_t sec,
3236
3254
time_t usec) {
3255
+ #ifdef __APPLE__
3256
+ if (sock >= FD_SETSIZE) { return Error::Connection; }
3257
+
3258
+ fd_set fdsr, fdsw;
3259
+ FD_ZERO (&fdsr);
3260
+ FD_ZERO (&fdsw);
3261
+ FD_SET (sock, &fdsr);
3262
+ FD_SET (sock, &fdsw);
3263
+
3264
+ timeval tv;
3265
+ tv.tv_sec = static_cast <long >(sec);
3266
+ tv.tv_usec = static_cast <decltype (tv.tv_usec )>(usec);
3267
+
3268
+ auto ret = handle_EINTR ([&]() {
3269
+ return select (static_cast <int >(sock + 1 ), &fdsr, &fdsw, nullptr , &tv);
3270
+ });
3271
+
3272
+ if (ret == 0 ) { return Error::ConnectionTimeout; }
3273
+
3274
+ if (ret > 0 && (FD_ISSET (sock, &fdsr) || FD_ISSET (sock, &fdsw))) {
3275
+ auto error = 0 ;
3276
+ socklen_t len = sizeof (error);
3277
+ auto res = getsockopt (sock, SOL_SOCKET, SO_ERROR,
3278
+ reinterpret_cast <char *>(&error), &len);
3279
+ auto successful = res >= 0 && !error;
3280
+ return successful ? Error::Success : Error::Connection;
3281
+ }
3282
+
3283
+ return Error::Connection;
3284
+ #else
3237
3285
struct pollfd pfd_read;
3238
3286
pfd_read.fd = sock;
3239
3287
pfd_read.events = POLLIN | POLLOUT;
@@ -3255,6 +3303,7 @@ inline Error wait_until_socket_is_ready(socket_t sock, time_t sec,
3255
3303
}
3256
3304
3257
3305
return Error::Connection;
3306
+ #endif
3258
3307
}
3259
3308
3260
3309
inline bool is_socket_alive (socket_t sock) {
@@ -8001,6 +8050,16 @@ Server::process_request(Stream &strm, const std::string &remote_addr,
8001
8050
res.version = " HTTP/1.1" ;
8002
8051
res.headers = default_headers_;
8003
8052
8053
+ #ifdef __APPLE__
8054
+ // Socket file descriptor exceeded FD_SETSIZE...
8055
+ if (strm.socket () >= FD_SETSIZE) {
8056
+ Headers dummy;
8057
+ detail::read_headers (strm, dummy);
8058
+ res.status = StatusCode::InternalServerError_500;
8059
+ return write_response (strm, close_connection, req, res);
8060
+ }
8061
+ #endif
8062
+
8004
8063
// Request line and headers
8005
8064
if (!parse_request_line (line_reader.ptr (), req) ||
8006
8065
!detail::read_headers (strm, req.headers )) {
0 commit comments