summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--ext/socket/lib/socket.rb79
-rw-r--r--lib/cgi/core.rb5
-rw-r--r--lib/drb/ssl.rb5
-rw-r--r--test/socket/test_socket.rb71
-rw-r--r--version.h6
6 files changed, 139 insertions, 37 deletions
diff --git a/ChangeLog b/ChangeLog
index 21e20ac6e2..70c4108136 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Wed Dec 25 00:18:19 2013 Tanaka Akira <akr@fsij.org>
+
+ * 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.
+
Tue Dec 24 00:18:14 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>
* lib/mkmf.rb (configuration): strip destdir part from prefix to get
diff --git a/ext/socket/lib/socket.rb b/ext/socket/lib/socket.rb
index ec3263c3fd..78b2ff45c2 100644
--- a/ext/socket/lib/socket.rb
+++ b/ext/socket/lib/socket.rb
@@ -64,13 +64,18 @@ class Addrinfo
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
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
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
@@ -353,8 +368,9 @@ class Socket < BasicSocket
# :stopdoc:
def self.ip_sockets_port0(ai_list, reuseaddr)
+ sockets = []
begin
- sockets = []
+ sockets.clear
port = nil
ai_list.each {|ai|
begin
@@ -375,14 +391,13 @@ class Socket < BasicSocket
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
@@ -391,12 +406,15 @@ class Socket < BasicSocket
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
@@ -440,9 +458,9 @@ class Socket < BasicSocket
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
@@ -455,8 +473,9 @@ class Socket < BasicSocket
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?
diff --git a/lib/cgi/core.rb b/lib/cgi/core.rb
index 27137a2032..1ab8e8c7d9 100644
--- a/lib/cgi/core.rb
+++ b/lib/cgi/core.rb
@@ -574,14 +574,15 @@ class CGI
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:
diff --git a/lib/drb/ssl.rb b/lib/drb/ssl.rb
index 8651702797..e7d9569eb6 100644
--- a/lib/drb/ssl.rb
+++ b/lib/drb/ssl.rb
@@ -328,8 +328,9 @@ module DRb
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
diff --git a/test/socket/test_socket.rb b/test/socket/test_socket.rb
index 659ebabba3..0628f94b00 100644
--- a/test/socket/test_socket.rb
+++ b/test/socket/test_socket.rb
@@ -548,4 +548,75 @@ class TestSocket < Test::Unit::TestCase
accepted.close if accepted
sock.close if sock && ! sock.closed?
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)
diff --git a/version.h b/version.h
index 886bf4bbeb..6ee4e9da8e 100644
--- a/version.h
+++ b/version.h
@@ -1,10 +1,10 @@
#define RUBY_VERSION "2.0.0"
-#define RUBY_RELEASE_DATE "2013-12-24"
-#define RUBY_PATCHLEVEL 373
+#define RUBY_RELEASE_DATE "2013-12-25"
+#define RUBY_PATCHLEVEL 374
#define RUBY_RELEASE_YEAR 2013
#define RUBY_RELEASE_MONTH 12
-#define RUBY_RELEASE_DAY 24
+#define RUBY_RELEASE_DAY 25
#include "ruby/version.h"