ruby-changes:9927
From: akr <ko1@a...>
Date: Mon, 12 Jan 2009 23:59:31 +0900 (JST)
Subject: [ruby-changes:9927] Ruby:r21468 (trunk): * ext/socket/socket.c (addrinfo_ip_unpack): new method
akr 2009-01-12 23:58:25 +0900 (Mon, 12 Jan 2009) New Revision: 21468 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=21468 Log: * ext/socket/socket.c (addrinfo_ip_unpack): new method AddrInfo#ip_unpack. (addrinfo_unix_path): new method AddrInfo#unix_path. (Init_socket): define above methods. Modified files: trunk/ChangeLog trunk/ext/socket/socket.c trunk/test/socket/test_addrinfo.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 21467) +++ ChangeLog (revision 21468) @@ -1,3 +1,10 @@ +Mon Jan 12 23:55:19 2009 Tanaka Akira <akr@f...> + + * ext/socket/socket.c (addrinfo_ip_unpack): new method + AddrInfo#ip_unpack. + (addrinfo_unix_path): new method AddrInfo#unix_path. + (Init_socket): define above methods. + Mon Jan 12 23:31:42 2009 Tanaka Akira <akr@f...> * ext/socket/socket.c (IS_IP_FAMILY): defined. Index: ext/socket/socket.c =================================================================== --- ext/socket/socket.c (revision 21467) +++ ext/socket/socket.c (revision 21468) @@ -5239,6 +5239,67 @@ /* * call-seq: + * addrinfo.ip_unpack => [addr, port] + * + * Returns the IP address and port number as 2-element array. + * + * AddrInfo.tcp("127.0.0.1", 80).ip_unpack #=> ["127.0.0.1", 80] + * AddrInfo.tcp("::1", 80).ip_unpack #=> ["::1", 80] + */ +static VALUE +addrinfo_ip_unpack(VALUE self) +{ + rb_addrinfo_t *rai = get_addrinfo(self); + int family = ai_get_afamily(rai); + VALUE vflags; + VALUE ret, portstr; + + if (!IS_IP_FAMILY(family)) + rb_raise(rb_eSocket, "need IPv4 or IPv6 address"); + + vflags = INT2NUM(NI_NUMERICHOST|NI_NUMERICSERV); + ret = addrinfo_getnameinfo(1, &vflags, self); + portstr = rb_ary_entry(ret, 1); + rb_ary_store(ret, 1, INT2NUM(atoi(StringValueCStr(portstr)))); + return ret; +} + +#ifdef HAVE_SYS_UN_H +/* + * call-seq: + * addrinfo.unix_path => path + * + * Returns the socket path as a string. + * + * AddrInfo.unix("/tmp/sock").unix_path #=> "/tmp/sock" + */ +static VALUE +addrinfo_unix_path(VALUE self) +{ + rb_addrinfo_t *rai = get_addrinfo(self); + int family = ai_get_afamily(rai); + struct sockaddr_un *addr; + char *s, *e; + + if (family != AF_UNIX) + rb_raise(rb_eSocket, "need AF_UNIX address"); + + addr = (struct sockaddr_un *)&rai->addr; + + s = addr->sun_path; + e = (char*)addr + rai->sockaddr_len; + if (e < s) + rb_raise(rb_eSocket, "too short AF_UNIX address"); + if (addr->sun_path + sizeof(addr->sun_path) < e) + rb_raise(rb_eSocket, "too long AF_UNIX address"); + while (s < e && *(e-1) == '\0') + e--; + return rb_str_new(s, e-s); +} +#endif + +/* + * call-seq: * AddrInfo.getaddrinfo(nodename, service, family, socktype, protocol, flags) => [addrinfo, ...] * AddrInfo.getaddrinfo(nodename, service, family, socktype, protocol) => [addrinfo, ...] * AddrInfo.getaddrinfo(nodename, service, family, socktype) => [addrinfo, ...] @@ -5521,10 +5582,14 @@ rb_define_method(rb_cAddrInfo, "protocol", addrinfo_protocol, 0); rb_define_method(rb_cAddrInfo, "canonname", addrinfo_canonname, 0); - rb_define_method(rb_cAddrInfo, "ip?", addrinfo_ip_p, 0); + rb_define_method(rb_cAddrInfo, "ip?", addrinfo_ip_p, 0); + rb_define_method(rb_cAddrInfo, "ip_unpack", addrinfo_ip_unpack, 0); rb_define_method(rb_cAddrInfo, "ipv4?", addrinfo_ipv4_p, 0); rb_define_method(rb_cAddrInfo, "ipv6?", addrinfo_ipv6_p, 0); rb_define_method(rb_cAddrInfo, "unix?", addrinfo_unix_p, 0); +#ifdef HAVE_SYS_UN_H + rb_define_method(rb_cAddrInfo, "unix_path", addrinfo_unix_path, 0); +#endif rb_define_method(rb_cAddrInfo, "to_sockaddr", addrinfo_to_sockaddr, 0); Index: test/socket/test_addrinfo.rb =================================================================== --- test/socket/test_addrinfo.rb (revision 21467) +++ test/socket/test_addrinfo.rb (revision 21468) @@ -25,6 +25,11 @@ assert_includes([0, Socket::IPPROTO_UDP], ai.protocol) end + def test_addrinfo_ip_unpack + ai = AddrInfo.tcp("127.0.0.1", 80) + assert_equal(["127.0.0.1", 80], ai.ip_unpack) + end + def test_addrinfo_new_inet ai = AddrInfo.new(["AF_INET", 46102, "localhost.localdomain", "127.0.0.2"]) assert_equal([46102, "127.0.0.2"], Socket.unpack_sockaddr_in(ai)) @@ -266,6 +271,11 @@ assert_equal(0, ai.protocol) end + def test_addrinfo_ip_unpack_inet6 + ai = AddrInfo.tcp("::1", 80) + assert_equal(["::1", 80], ai.ip_unpack) + end + end if defined?(UNIXSocket) && /cygwin/ !~ RUBY_PLATFORM @@ -279,6 +289,11 @@ assert_equal(0, ai.protocol) end + def test_addrinfo_unix_path + ai = AddrInfo.unix("/tmp/sock1") + assert_equal("/tmp/sock1", ai.unix_path) + end + def test_addrinfo_new_unix ai = AddrInfo.new(["AF_UNIX", "/tmp/sock"]) assert_equal("/tmp/sock", Socket.unpack_sockaddr_un(ai)) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/