Project

General

Profile

Bug #9247

Updated by mrkn (Kenta Murata) over 10 years ago


 Ruby 2.1 (trunk) 2.0 and 1.9.3 both has a bug to retrieve exception. 
 In the following code, opened socket is always closed. 

 require 'socket' 
 ai = Addrinfo.tcp(nil, 12345) 
 begin 
   raise 
 rescue 
   p ai.listen #=> #<Socket:(closed)> 
 end 

 This is because in socket.rb, there are such error handling code: 

   # creates a listening socket bound to self. 
   def listen(backlog=Socket::SOMAXCONN) 
     sock = Socket.new(self.pfamily, self.socktype, self.protocol) 
     begin 
       sock.ipv6only! if self.ipv6? 
       sock.setsockopt(:SOCKET, :REUSEADDR, 1) 
       sock.bind(self) 
       sock.listen(backlog) 
       if block_given? 
         yield sock 
       else 
         sock 
       end 
     ensure 
       ### THIS LINE CLOSE `sock' every time when $! is not nil 
       sock.close if !sock.closed? && (block_given? || $!) 
     end 
   end 

 There are similar code in socket.rb. 

 akr-san already knows this issue. 
 This ticket is to note issues. 


 We realize this issue because webrick use this feature from 2.1. 
 The following code no longer works on 2.1. 

   begin 
     require 'xyzzy' # something like webrick 
   rescue LoadError 
     require 'webrick'  
     server = WEBrick::HTTPServer.new(Port: 12345) 
   end 

 Because $! is an instance of LoadError. 

Back