summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-12-31 15:05:16 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-12-31 15:05:16 +0000
commitddedc6f125e2506f539f0ed81b0e144c07c27442 (patch)
tree61f7846d781aa023205dc33d3c8af5f68ae3d717
parent95c474ec4dba7e919511bb0d02832a83fbb04813 (diff)
* ext/socket/socket.c (sock_s_socketpair): yield if a block is given.
(io_call_close): defined. (io_close): defined. (pair_yield): defined. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@21216 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog7
-rw-r--r--ext/socket/socket.c28
-rw-r--r--test/socket/test_unix.rb20
3 files changed, 53 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 5436581640..414cc1d5a5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Wed Dec 31 23:37:17 2008 Tanaka Akira <akr@fsij.org>
+
+ * ext/socket/socket.c (sock_s_socketpair): yield if a block is given.
+ (io_call_close): defined.
+ (io_close): defined.
+ (pair_yield): defined.
+
Wed Dec 31 19:35:57 2008 Yuki Sonoda (Yugui) <yugui@yugui.jp>
* spec/README: follows the change of directory structure in rubyspec.
diff --git a/ext/socket/socket.c b/ext/socket/socket.c
index b9de752d71..11976b01a4 100644
--- a/ext/socket/socket.c
+++ b/ext/socket/socket.c
@@ -2385,11 +2385,30 @@ sock_initialize(VALUE sock, VALUE domain, VALUE type, VALUE protocol)
}
static VALUE
+io_call_close(VALUE io)
+{
+ return rb_funcall(io, rb_intern("close"), 0, 0);
+}
+
+static VALUE
+io_close(VALUE io)
+{
+ return rb_rescue(io_call_close, io, 0, 0);
+}
+
+static VALUE
+pair_yield(VALUE pair)
+{
+ return rb_ensure(rb_yield, pair, io_close, rb_ary_entry(pair, 1));
+}
+
+static VALUE
sock_s_socketpair(VALUE klass, VALUE domain, VALUE type, VALUE protocol)
{
#if defined HAVE_SOCKETPAIR
int d, t, p, sp[2];
int ret;
+ VALUE s1, s2, r;
setup_domain_and_type(domain, &d, type, &t);
p = NUM2INT(protocol);
@@ -2402,8 +2421,13 @@ sock_s_socketpair(VALUE klass, VALUE domain, VALUE type, VALUE protocol)
rb_sys_fail("socketpair(2)");
}
- return rb_assoc_new(init_sock(rb_obj_alloc(klass), sp[0]),
- init_sock(rb_obj_alloc(klass), sp[1]));
+ s1 = init_sock(rb_obj_alloc(klass), sp[0]);
+ s2 = init_sock(rb_obj_alloc(klass), sp[1]);
+ r = rb_assoc_new(s1, s2);
+ if (rb_block_given_p()) {
+ return rb_ensure(pair_yield, r, io_close, s1);
+ }
+ return r;
#else
rb_notimplement();
#endif
diff --git a/test/socket/test_unix.rb b/test/socket/test_unix.rb
index 58350c4486..5b041f1733 100644
--- a/test/socket/test_unix.rb
+++ b/test/socket/test_unix.rb
@@ -146,4 +146,24 @@ class TestUNIXSocket < Test::Unit::TestCase
assert_equal("a", s1.read(1))
end
+ def test_socket_pair_with_block
+ pair = nil
+ ret = Socket.pair(Socket::AF_UNIX, Socket::SOCK_STREAM, 0) {|s1, s2|
+ pair = [s1, s2]
+ :return_value
+ }
+ assert_equal(:return_value, ret)
+ assert_kind_of(Socket, pair[0])
+ assert_kind_of(Socket, pair[1])
+ end
+
+ def test_unix_socket_pair_with_block
+ pair = nil
+ UNIXSocket.pair {|s1, s2|
+ pair = [s1, s2]
+ }
+ assert_kind_of(UNIXSocket, pair[0])
+ assert_kind_of(UNIXSocket, pair[1])
+ end
+
end if defined?(UNIXSocket) && /cygwin/ !~ RUBY_PLATFORM