ruby-changes:11055
From: akr <ko1@a...>
Date: Thu, 26 Feb 2009 23:22:45 +0900 (JST)
Subject: [ruby-changes:11055] Ruby:r22649 (trunk): * ext/socket/lib/socket.rb (BasicSocket#connect_address): new method.
akr 2009-02-26 23:15:39 +0900 (Thu, 26 Feb 2009) New Revision: 22649 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=22649 Log: * ext/socket/lib/socket.rb (BasicSocket#connect_address): new method. Modified files: trunk/ChangeLog trunk/NEWS trunk/ext/socket/lib/socket.rb trunk/test/socket/test_socket.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 22648) +++ ChangeLog (revision 22649) @@ -1,3 +1,7 @@ +Thu Feb 26 23:14:46 2009 Tanaka Akira <akr@f...> + + * ext/socket/lib/socket.rb (BasicSocket#connect_address): new method. + Thu Feb 26 19:29:10 2009 Nobuyoshi Nakada <nobu@r...> * hash.c (hash_foreach_iter): fix for prototype. Index: ext/socket/lib/socket.rb =================================================================== --- ext/socket/lib/socket.rb (revision 22648) +++ ext/socket/lib/socket.rb (revision 22649) @@ -158,6 +158,46 @@ end end +class BasicSocket + # Returns an address of the socket suitable for connect. + # + # This method returns _self_.local_address, except following condition. + # + # - IPv4 unspecified address (0.0.0.0) is replaced by IPv4 loopback address (127.0.0.1). + # - IPv6 unspecified address (::) is replaced by IPv6 loopback address (::1). + # + # If the local address is not suitable for connect, SocketError is raised. + # IPv4 and IPv6 address which port is 0 is not suitable for connect. + # Unix domain socket which has no path is not suitable for connect. + # + # Addrinfo.tcp("0.0.0.0", 0).listen {|serv| + # p serv.connect_address #=> #<Addrinfo: 127.0.0.1:53660 TCP> + # serv.connect_address.connect {|c| + # s, _ = serv.accept + # p [c, s] #=> [#<Socket:fd 4>, #<Socket:fd 6>] + # } + # } + # + def connect_address + addr = local_address + afamily = addr.afamily + if afamily == Socket::AF_INET + raise SocketError, "unbound IPv4 socket" if addr.ip_port == 0 + if addr.ip_address == "0.0.0.0" + addr = Addrinfo.new(["AF_INET", addr.ip_port, nil, "127.0.0.1"], addr.pfamily, addr.socktype, addr.protocol) + end + elsif defined?(Socket::AF_INET6) && afamily == Socket::AF_INET6 + raise SocketError, "unbound IPv6 socket" if addr.ip_port == 0 + if addr.ip_address == "::" + addr = Addrinfo.new(["AF_INET6", addr.ip_port, nil, "::1"], addr.pfamily, addr.socktype, addr.protocol) + end + elsif defined?(Socket::AF_UNIX) && afamily == Socket::AF_UNIX + raise SocketError, "unbound Unix socket" if addr.unix_path == "" + end + addr + end +end + class Socket # enable the socket option IPV6_V6ONLY if IPV6_V6ONLY is available. def ipv6only! Index: NEWS =================================================================== --- NEWS (revision 22648) +++ NEWS (revision 22649) @@ -112,6 +112,7 @@ * Socket#ipv6only! * BasicSocket#local_address * BasicSocket#remote_address + * BasicSocket#connect_address * BasicSocket#sendmsg * BasicSocket#sendmsg_nonblock * BasicSocket#recvmsg Index: test/socket/test_socket.rb =================================================================== --- test/socket/test_socket.rb (revision 22648) +++ test/socket/test_socket.rb (revision 22649) @@ -73,22 +73,9 @@ } end - def tcp_unspecified_to_loopback(addrinfo) - if addrinfo.ipv4? && addrinfo.ip_address == "0.0.0.0" - Addrinfo.tcp("127.0.0.1", addrinfo.ip_port) - elsif addrinfo.ipv6? && addrinfo.ipv6_unspecified? - Addrinfo.tcp("::1", addrinfo.ip_port) - elsif addrinfo.ipv6? && (ai = addrinfo.ipv6_to_ipv4) && ai.ip_address == "0.0.0.0" - Addrinfo.tcp("127.0.0.1", addrinfo.ip_port) - else - addrinfo - end - end - def test_tcp TCPServer.open(0) {|serv| - addr = serv.local_address - addr = tcp_unspecified_to_loopback(addr) + addr = serv.connect_address addr.connect {|s1| s2 = serv.accept begin @@ -185,7 +172,7 @@ tcp_servers = Socket.tcp_server_sockets(0) unix_server = Socket.unix_server_socket("#{tmpdir}/sock") tcp_servers.each {|s| - addr = tcp_unspecified_to_loopback(s.local_address) + addr = s.connect_address clients << addr.connect } clients << unix_server.local_address.connect -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/