diff --git a/lib/socket.rb b/lib/socket.rb index 5ef7deb296..32a8bdcbaa 100644 --- a/lib/socket.rb +++ b/lib/socket.rb @@ -1034,52 +1034,62 @@ def tcp_setup(remote_host, remote_service, local_host = nil, Socket::SOCK_STREAM, 0, 0) end + sock = nil + @remote_addrinfo.each do |addrinfo| flags, family, socket_type, protocol, sockaddr, canonname = addrinfo - status = Socket::Foreign.socket family, socket_type, protocol + sock = Socket::Foreign.socket family, socket_type, protocol syscall = 'socket(2)' - IO.setup self, status, nil, true - next if descriptor < 0 + next if sock < 0 - if server then + if server status = 1 begin + IO.setup self, sock, nil, true setsockopt(Socket::Constants::SOL_SOCKET, Socket::Constants::SO_REUSEADDR, true) rescue SystemCallError end - status = Socket::Foreign.bind descriptor, sockaddr + status = Socket::Foreign.bind sock, sockaddr syscall = 'bind(2)' else - if @local_addrinfo then - status = bind descriptor, @local_addrinfo.first[4] + if @local_addrinfo + status = bind sock, @local_addrinfo.first[4] syscall = 'bind(2)' + else + status = 1 end - if status >= 0 then - status = Socket::Foreign.connect descriptor, sockaddr + if status >= 0 + status = Socket::Foreign.connect sock, sockaddr syscall = 'connect(2)' end end - break if status >= 0 + if status < 0 + Socket::Foreign.close sock + else + break + end end if status < 0 Errno.handle syscall - Socket::Foreign.close descriptor end - if server then - err = Socket::Foreign.listen descriptor, 5 - Errno.handle syscall unless err == 0 + if server + err = Socket::Foreign.listen sock, 5 + unless err == 0 + Socket::Foreign.close sock + Errno.handle syscall + end end - IO.setup self, descriptor, nil, true + IO.setup self, sock, nil, true end private :tcp_setup