- int err;
- socklen_t len= sizeof (err);
- (void)getsockopt(ptr->fd, SOL_SOCKET, SO_ERROR, &err, &len);
+ int local_errno= get_socket_errno(); // We cache in case closesocket() modifies errno
+ switch (local_errno)
+ {
+#ifdef TARGET_OS_LINUX
+ case ERESTART:
+#endif
+ case EINTR:
+ continue;
+
+ case EFAULT:
+ case ENOMEM:
+ return memcached_set_error(*server, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT);
+
+ case EINVAL:
+ return memcached_set_error(*server, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT, memcached_literal_param("RLIMIT_NOFILE exceeded, or if OSX the timeout value was invalid"));
+
+ default: // This should not happen
+ if (fds[0].revents & POLLERR)
+ {
+ int err;
+ socklen_t len= sizeof(err);
+ if (getsockopt(server->fd, SOL_SOCKET, SO_ERROR, &err, &len) == 0)
+ {
+ if (err == 0)
+ {
+ // This should never happen, if it does? Punt.
+ continue;
+ }
+ local_errno= err;
+ }
+ }
+
+ assert_msg(server->fd != INVALID_SOCKET, "poll() was passed an invalid file descriptor");
+ (void)closesocket(server->fd);
+ server->fd= INVALID_SOCKET;
+ server->state= MEMCACHED_SERVER_STATE_NEW;
+
+ return memcached_set_errno(*server, local_errno, MEMCACHED_AT);
+ }
+ }
+ assert(number_of == 0);