[前][次][番号順一覧][スレッド一覧]

ruby-changes:32105

From: akr <ko1@a...>
Date: Sat, 14 Dec 2013 01:11:23 +0900 (JST)
Subject: [ruby-changes:32105] akr:r44184 (trunk): * ext/socket/lib/socket.rb: Don't test $! in "ensure" clause because

akr	2013-12-14 01:11:12 +0900 (Sat, 14 Dec 2013)

  New Revision: 44184

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=44184

  Log:
    * ext/socket/lib/socket.rb: Don't test $! in "ensure" clause because
      it may be set before the body.
      Reported by ko1 and mrkn.  [ruby-core:59088] [Bug #9247]
    
    * lib/cgi/core.rb: Ditto.
    
    * lib/drb/ssl.rb: Ditto.

  Modified files:
    trunk/ChangeLog
    trunk/ext/socket/lib/socket.rb
    trunk/lib/cgi/core.rb
    trunk/lib/drb/ssl.rb
    trunk/test/socket/test_socket.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 44183)
+++ ChangeLog	(revision 44184)
@@ -1,3 +1,13 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sat Dec 14 01:05:46 2013  Tanaka Akira  <akr@f...>
+
+	* ext/socket/lib/socket.rb: Don't test $! in "ensure" clause because
+	  it may be set before the body.
+	  Reported by ko1 and mrkn.  [ruby-core:59088] [Bug #9247]
+
+	* lib/cgi/core.rb: Ditto.
+
+	* lib/drb/ssl.rb: Ditto.
+
 Sat Dec 14 00:34:31 2013  Naohisa Goto  <ngotogenome@g...>
 
 	* internal.h (ruby_sized_xrealloc2): fix typo introduced in r44117,
Index: lib/cgi/core.rb
===================================================================
--- lib/cgi/core.rb	(revision 44183)
+++ lib/cgi/core.rb	(revision 44184)
@@ -574,14 +574,15 @@ class CGI https://github.com/ruby/ruby/blob/trunk/lib/cgi/core.rb#L574
       raise EOFError, "bad boundary end of body part" unless boundary_end =~ /--/
       params.default = []
       params
-    ensure
-      if $! && tempfiles
+    rescue Exception
+      if tempfiles
         tempfiles.each {|t|
           if t.path
             t.unlink
           end
         }
       end
+      raise
     end # read_multipart
     private :read_multipart
     def create_body(is_large)  #:nodoc:
Index: lib/drb/ssl.rb
===================================================================
--- lib/drb/ssl.rb	(revision 44183)
+++ lib/drb/ssl.rb	(revision 44184)
@@ -328,8 +328,9 @@ module DRb https://github.com/ruby/ruby/blob/trunk/lib/drb/ssl.rb#L328
       end
       begin
 	ssl = @config.accept(soc)
-      ensure
-        soc.close if $!
+      rescue Exception
+        soc.close
+        raise
       end
       self.class.new(uri, ssl, @config, true)
       rescue OpenSSL::SSL::SSLError
Index: ext/socket/lib/socket.rb
===================================================================
--- ext/socket/lib/socket.rb	(revision 44183)
+++ ext/socket/lib/socket.rb	(revision 44184)
@@ -64,13 +64,18 @@ class Addrinfo https://github.com/ruby/ruby/blob/trunk/ext/socket/lib/socket.rb#L64
       else
         sock.connect(self)
       end
-      if block_given?
+    rescue Exception
+      sock.close
+      raise
+    end
+    if block_given?
+      begin
         yield sock
-      else
-        sock
+      ensure
+        sock.close if !sock.closed?
       end
-    ensure
-      sock.close if !sock.closed? && (block_given? || $!)
+    else
+      sock
     end
   end
   private :connect_internal
@@ -177,13 +182,18 @@ class Addrinfo https://github.com/ruby/ruby/blob/trunk/ext/socket/lib/socket.rb#L182
       sock.ipv6only! if self.ipv6?
       sock.setsockopt(:SOCKET, :REUSEADDR, 1)
       sock.bind(self)
-      if block_given?
+    rescue Exception
+      sock.close
+      raise
+    end
+    if block_given?
+      begin
         yield sock
-      else
-        sock
+      ensure
+        sock.close if !sock.closed?
       end
-    ensure
-      sock.close if !sock.closed? && (block_given? || $!)
+    else
+      sock
     end
   end
 
@@ -195,13 +205,18 @@ class Addrinfo https://github.com/ruby/ruby/blob/trunk/ext/socket/lib/socket.rb#L205
       sock.setsockopt(:SOCKET, :REUSEADDR, 1)
       sock.bind(self)
       sock.listen(backlog)
-      if block_given?
+    rescue Exception
+      sock.close
+      raise
+    end
+    if block_given?
+      begin
         yield sock
-      else
-        sock
+      ensure
+        sock.close if !sock.closed?
       end
-    ensure
-      sock.close if !sock.closed? && (block_given? || $!)
+    else
+      sock
     end
   end
 
@@ -348,8 +363,9 @@ class Socket < BasicSocket https://github.com/ruby/ruby/blob/trunk/ext/socket/lib/socket.rb#L363
 
   # :stopdoc:
   def self.ip_sockets_port0(ai_list, reuseaddr)
+    sockets = []
     begin
-      sockets = []
+      sockets.clear
       port = nil
       ai_list.each {|ai|
         begin
@@ -370,14 +386,13 @@ class Socket < BasicSocket https://github.com/ruby/ruby/blob/trunk/ext/socket/lib/socket.rb#L386
         end
       }
     rescue Errno::EADDRINUSE
-      sockets.each {|s|
-        s.close
-      }
+      sockets.each {|s| s.close }
       retry
+    rescue Exception
+      sockets.each {|s| s.close }
+      raise
     end
     sockets
-  ensure
-    sockets.each {|s| s.close if !s.closed? } if $!
   end
   class << self
     private :ip_sockets_port0
@@ -386,12 +401,15 @@ class Socket < BasicSocket https://github.com/ruby/ruby/blob/trunk/ext/socket/lib/socket.rb#L401
   def self.tcp_server_sockets_port0(host)
     ai_list = Addrinfo.getaddrinfo(host, 0, nil, :STREAM, nil, Socket::AI_PASSIVE)
     sockets = ip_sockets_port0(ai_list, true)
-    sockets.each {|s|
-      s.listen(Socket::SOMAXCONN)
-    }
+    begin
+      sockets.each {|s|
+        s.listen(Socket::SOMAXCONN)
+      }
+    rescue Exception
+      sockets.each {|s| s.close }
+      raise
+    end
     sockets
-  ensure
-    sockets.each {|s| s.close if !s.closed? } if $! && sockets
   end
   class << self
     private :tcp_server_sockets_port0
@@ -435,9 +453,9 @@ class Socket < BasicSocket https://github.com/ruby/ruby/blob/trunk/ext/socket/lib/socket.rb#L453
     if port == 0
       sockets = tcp_server_sockets_port0(host)
     else
+      last_error = nil
+      sockets = []
       begin
-        last_error = nil
-        sockets = []
         Addrinfo.foreach(host, port, nil, :STREAM, nil, Socket::AI_PASSIVE) {|ai|
           begin
             s = ai.listen
@@ -450,8 +468,9 @@ class Socket < BasicSocket https://github.com/ruby/ruby/blob/trunk/ext/socket/lib/socket.rb#L468
         if sockets.empty?
           raise last_error
         end
-      ensure
-        sockets.each {|s| s.close if !s.closed? } if $!
+      rescue Exception
+        sockets.each {|s| s.close }
+        raise
       end
     end
     if block_given?
Index: test/socket/test_socket.rb
===================================================================
--- test/socket/test_socket.rb	(revision 44183)
+++ test/socket/test_socket.rb	(revision 44184)
@@ -575,4 +575,75 @@ class TestSocket < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/socket/test_socket.rb#L575
       assert_instance_of(Socket::Ifaddr, ifaddr)
     }
   end
+
+  def test_connect_in_rescue
+    serv = Addrinfo.tcp(nil, 0).listen
+    addr = serv.connect_address
+    begin
+      raise "dummy error"
+    rescue
+      s = addr.connect
+      assert(!s.closed?)
+    end
+  ensure
+    serv.close if serv && !serv.closed?
+    s.close if s && !s.closed?
+  end
+
+  def test_bind_in_rescue
+    begin
+      raise "dummy error"
+    rescue
+      s = Addrinfo.tcp(nil, 0).bind
+      assert(!s.closed?)
+    end
+  ensure
+    s.close if s && !s.closed?
+  end
+
+  def test_listen_in_rescue
+    begin
+      raise "dummy error"
+    rescue
+      s = Addrinfo.tcp(nil, 0).listen
+      assert(!s.closed?)
+    end
+  ensure
+    s.close if s && !s.closed?
+  end
+
+  def test_udp_server_sockets_in_rescue
+    begin
+      raise "dummy error"
+    rescue
+      ss = Socket.udp_server_sockets(0)
+      ss.each {|s|
+        assert(!s.closed?)
+      }
+    end
+  ensure
+    if ss
+      ss.each {|s|
+        s.close if !s.closed?
+      }
+    end
+  end
+
+  def test_tcp_server_sockets_in_rescue
+    begin
+      raise "dummy error"
+    rescue
+      ss = Socket.tcp_server_sockets(0)
+      ss.each {|s|
+        assert(!s.closed?)
+      }
+    end
+  ensure
+    if ss
+      ss.each {|s|
+        s.close if !s.closed?
+      }
+    end
+  end
+
 end if defined?(Socket)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]