diff --git a/bundler/lib/bundler/mirror.rb b/bundler/lib/bundler/mirror.rb index 494a6d6aef18..234c6bd37dcf 100644 --- a/bundler/lib/bundler/mirror.rb +++ b/bundler/lib/bundler/mirror.rb @@ -160,18 +160,18 @@ def replies?(mirror) def wait_for_writtable_socket(socket, address, timeout) if IO.select(nil, [socket], nil, timeout) - probe_writtable_socket(socket, address) + probe_writtable_socket(socket) else # TCP Handshake timed out, or there is something dropping packets false end end - def probe_writtable_socket(socket, address) - socket.connect_nonblock(address) - rescue Errno::EISCONN - true - rescue StandardError # Connection failed - false + def probe_writtable_socket(socket) + # Check the pending error on the socket rather than calling + # +connect_nonblock+ a second time. On BSD-based systems such as macOS a + # second connect returns +EISCONN+ even when the asynchronous connect + # failed, which would make a down mirror look reachable. + socket.getsockopt(Socket::SOL_SOCKET, Socket::SO_ERROR).int == 0 end end end