Skip to content

Commit

Permalink
Be sure to not leak fds when trying many addresses. Fixes rubinius#653
Browse files Browse the repository at this point in the history
  • Loading branch information
Evan Phoenix committed Feb 15, 2011
1 parent c2e9b23 commit f36048f
Showing 1 changed file with 25 additions and 15 deletions.
40 changes: 25 additions & 15 deletions lib/socket.rb
Expand Up @@ -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

Expand Down

0 comments on commit f36048f

Please sign in to comment.