summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-02-22 03:01:21 +0000
committernagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-02-22 03:01:21 +0000
commitdac4cd841af72c142342a39a34cfff371e93347e (patch)
tree59e79dc2cb34211f010e4fd9255780a6c75ac9fb
parent8c6dd375a7fc4da62b49475bce5ea5a64105e5cd (diff)
merge revision(s) r45066: [Backport #9550]
* ext/socket/ancdata.c (bsock_sendmsg_internal): only retry on error (bsock_recvmsg_internal): ditto * test/socket/test_unix.rb: test above for infinite loop git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_0_0@45098 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog6
-rw-r--r--ext/socket/ancdata.c18
-rw-r--r--test/socket/test_unix.rb23
-rw-r--r--version.h2
4 files changed, 38 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 6916f7c0ff..2db56e5c18 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Sat Feb 22 11:50:52 2014 Eric Wong <e@80x24.org>
+
+ * ext/socket/ancdata.c (bsock_sendmsg_internal): only retry on error
+ (bsock_recvmsg_internal): ditto
+ * test/socket/test_unix.rb: test above for infinite loop
+
Sat Feb 22 11:44:50 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
* class.c (rb_mod_init_copy): do nothing if copying self.
diff --git a/ext/socket/ancdata.c b/ext/socket/ancdata.c
index 050da974c4..37d2860224 100644
--- a/ext/socket/ancdata.c
+++ b/ext/socket/ancdata.c
@@ -1280,12 +1280,11 @@ bsock_sendmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock)
ss = rb_sendmsg(fptr->fd, &mh, flags);
- if (!nonblock && rb_io_wait_writable(fptr->fd)) {
- rb_io_check_closed(fptr);
- goto retry;
- }
-
if (ss == -1) {
+ if (!nonblock && rb_io_wait_writable(fptr->fd)) {
+ rb_io_check_closed(fptr);
+ goto retry;
+ }
if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN))
rb_mod_sys_fail(rb_mWaitWritable, "sendmsg(2) would block");
rb_sys_fail("sendmsg(2)");
@@ -1589,12 +1588,11 @@ bsock_recvmsg_internal(int argc, VALUE *argv, VALUE sock, int nonblock)
ss = rb_recvmsg(fptr->fd, &mh, flags);
- if (!nonblock && rb_io_wait_readable(fptr->fd)) {
- rb_io_check_closed(fptr);
- goto retry;
- }
-
if (ss == -1) {
+ if (!nonblock && rb_io_wait_readable(fptr->fd)) {
+ rb_io_check_closed(fptr);
+ goto retry;
+ }
if (nonblock && (errno == EWOULDBLOCK || errno == EAGAIN))
rb_mod_sys_fail(rb_mWaitReadable, "recvmsg(2) would block");
#if defined(HAVE_ST_MSG_CONTROL)
diff --git a/test/socket/test_unix.rb b/test/socket/test_unix.rb
index faf70f2e19..eae236a60b 100644
--- a/test/socket/test_unix.rb
+++ b/test/socket/test_unix.rb
@@ -5,6 +5,7 @@ end
require "test/unit"
require "tempfile"
+require "timeout"
require "tmpdir"
require "thread"
require "io/nonblock"
@@ -363,6 +364,28 @@ class TestSocket_UNIXSocket < Test::Unit::TestCase
s2.close if s2
end
+ def test_dgram_pair_sendrecvmsg_errno_set
+ s1, s2 = to_close = UNIXSocket.pair(Socket::SOCK_DGRAM)
+ pipe = IO.pipe
+ to_close.concat(pipe)
+ set_errno = lambda do
+ begin
+ pipe[0].read_nonblock(1)
+ fail
+ rescue => e
+ assert(IO::WaitReadable === e)
+ end
+ end
+ Timeout.timeout(10) do
+ set_errno.call
+ assert_equal(2, s1.sendmsg("HI"))
+ set_errno.call
+ assert_equal("HI", s2.recvmsg[0])
+ end
+ ensure
+ to_close.each(&:close) if to_close
+ end
+
def test_epipe # [ruby-dev:34619]
s1, s2 = UNIXSocket.pair
s1.shutdown(Socket::SHUT_WR)
diff --git a/version.h b/version.h
index fe2c1a41c1..c3950e4e71 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
#define RUBY_VERSION "2.0.0"
#define RUBY_RELEASE_DATE "2014-02-22"
-#define RUBY_PATCHLEVEL 444
+#define RUBY_PATCHLEVEL 445
#define RUBY_RELEASE_YEAR 2014
#define RUBY_RELEASE_MONTH 2