ruby-changes:28957
From: naruse <ko1@a...>
Date: Sat, 1 Jun 2013 02:38:13 +0900 (JST)
Subject: [ruby-changes:28957] naruse:r41009 (trunk): * ext/socket/option.c (sockopt_s_byte): constructor of the sockopt
naruse 2013-06-01 02:37:55 +0900 (Sat, 01 Jun 2013) New Revision: 41009 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=41009 Log: * ext/socket/option.c (sockopt_s_byte): constructor of the sockopt whose value's is byte. * ext/socket/option.c (sockopt_byte): getter for above. * ext/socket/option.c (inspect_byte): inspect for above. * ext/socket/option.c (sockopt_s_ip_multicast_loop): constructor of the sockopt whose optname is IP_MULTICAST_LOOP. * ext/socket/option.c (sockopt_ip_multicast_loop): getter for above. * ext/socket/option.c (sockopt_s_ip_multicast_ttl): constructor of the sockopt whose optname is IP_MULTICAST_TTL. * ext/socket/option.c (sockopt_ip_multicast_ttl): getter for above. * ext/socket/option.c (sockopt_inspect): use above. Modified files: trunk/ChangeLog trunk/ext/socket/option.c trunk/test/socket/test_sockopt.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 41008) +++ ChangeLog (revision 41009) @@ -1,3 +1,24 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sat Jun 1 02:37:35 2013 NARUSE, Yui <naruse@r...> + + * ext/socket/option.c (sockopt_s_byte): constructor of the sockopt + whose value's is byte. + + * ext/socket/option.c (sockopt_byte): getter for above. + + * ext/socket/option.c (inspect_byte): inspect for above. + + * ext/socket/option.c (sockopt_s_ip_multicast_loop): constructor of + the sockopt whose optname is IP_MULTICAST_LOOP. + + * ext/socket/option.c (sockopt_ip_multicast_loop): getter for above. + + * ext/socket/option.c (sockopt_s_ip_multicast_ttl): constructor of + the sockopt whose optname is IP_MULTICAST_TTL. + + * ext/socket/option.c (sockopt_ip_multicast_ttl): getter for above. + + * ext/socket/option.c (sockopt_inspect): use above. + Sat Jun 01 01:50:00 2013 Kenta Murata <mrkn@m...> * ext/bigdecimal/bigdecimal.c (BigDecimal_power): use rb_dbl2big Index: ext/socket/option.c =================================================================== --- ext/socket/option.c (revision 41008) +++ ext/socket/option.c (revision 41009) @@ -144,6 +144,50 @@ sockopt_data(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/socket/option.c#L144 /* * call-seq: + * Socket::Option.byte(family, level, optname, integer) => sockopt + * + * Creates a new Socket::Option object which contains a byte as data. + * + * The size and endian is dependent on the platform. + * + * p Socket::Option.byte(:INET, :SOCKET, :KEEPALIVE, 1) + * #=> #<Socket::Option: INET SOCKET KEEPALIVE 1> + */ +static VALUE +sockopt_s_byte(VALUE klass, VALUE vfamily, VALUE vlevel, VALUE voptname, VALUE vint) +{ + int family = rsock_family_arg(vfamily); + int level = rsock_level_arg(family, vlevel); + int optname = rsock_optname_arg(family, level, voptname); + unsigned char i = (unsigned char)NUM2CHR(vint); + return rsock_sockopt_new(family, level, optname, rb_str_new((char*)&i, sizeof(i))); +} + +/* + * call-seq: + * sockopt.byte => integer + * + * Returns the data in _sockopt_ as an byte. + * + * The size and endian is dependent on the platform. + * + * sockopt = Socket::Option.byte(:INET, :SOCKET, :KEEPALIVE, 1) + * p sockopt.byte => 1 + */ +static VALUE +sockopt_byte(VALUE self) +{ + unsigned char i; + VALUE data = sockopt_data(self); + StringValue(data); + if (RSTRING_LEN(data) != sizeof(i)) + rb_raise(rb_eTypeError, "size differ. expected as sizeof(int)=%d but %ld", + (int)sizeof(i), (long)RSTRING_LEN(data)); + return CHR2FIX(*RSTRING_PTR(data)); +} + +/* + * call-seq: * Socket::Option.int(family, level, optname, integer) => sockopt * * Creates a new Socket::Option object which contains an int as data. @@ -294,6 +338,138 @@ sockopt_linger(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/socket/option.c#L338 return rb_assoc_new(vonoff, vsecs); } +/* + * call-seq: + * Socket::Option.ip_multicast_loop(integer) => sockopt + * + * Creates a new Socket::Option object for IP_MULTICAST_LOOP. + * + * The size is dependent on the platform. + * + * sockopt = Socket::Option.int(:INET, :IPPROTO_IP, :IP_MULTICAST_LOOP, 1) + * p sockopt.int => 1 + * + * p Socket::Option.ip_multicast_loop(10) + * #=> #<Socket::Option: INET IP MULTICAST_LOOP 10> + * + */ +static VALUE +sockopt_s_ip_multicast_loop(VALUE klass, VALUE value) +{ +#if defined(IPPROTO_IP) && defined(IP_MULTICAST_LOOP) +# ifdef __NetBSD__ + unsigned char i = NUM2CHR(rb_to_int(value)); +# else + int i = NUM2INT(rb_to_int(value)); +# endif + return rsock_sockopt_new(AF_INET, IPPROTO_IP, IP_MULTICAST_LOOP, + rb_str_new((char*)&i, sizeof(i))); +#else +# error IPPROTO_IP or IP_MULTICAST_LOOP is not implemented +#endif +} + +/* + * call-seq: + * sockopt.ip_multicast_loop => integer + * + * Returns the ip_multicast_loop data in _sockopt_ as a integer. + * + * sockopt = Socket::Option.ip_multicast_loop(10) + * p sockopt.ip_multicast_loop => 10 + */ +static VALUE +sockopt_ip_multicast_loop(VALUE self) +{ + int family = NUM2INT(sockopt_family_m(self)); + int level = sockopt_level(self); + int optname = sockopt_optname(self); + +#if defined(IPPROTO_IP) && defined(IP_MULTICAST_LOOP) + if (family == AF_INET && level == IPPROTO_IP && optname == IP_MULTICAST_LOOP) { +# ifdef __NetBSD__ + return sockopt_byte(self); +# else + return sockopt_int(self); +# endif + } +#endif + rb_raise(rb_eTypeError, "ip_multicast_loop socket option expected"); + UNREACHABLE; +} + +#ifdef __NetBSD__ +# define inspect_ip_multicast_loop(a,b,c,d) inspect_byte(a,b,c,d) +#else +# define inspect_ip_multicast_loop(a,b,c,d) inspect_int(a,b,c,d) +#endif + +/* + * call-seq: + * Socket::Option.ip_multicast_ttl(integer) => sockopt + * + * Creates a new Socket::Option object for IP_MULTICAST_TTL. + * + * The size is dependent on the platform. + * + * p Socket::Option.ip_multicast_ttl(10) + * #=> #<Socket::Option: INET IP MULTICAST_TTL 10> + * + */ +static VALUE +sockopt_s_ip_multicast_ttl(VALUE klass, VALUE value) +{ +#if defined(IPPROTO_IP) && defined(IP_MULTICAST_TTL) +# ifdef __NetBSD__ + unsigned char i = NUM2CHR(rb_to_int(value)); +# else + int i = NUM2INT(rb_to_int(value)); +# endif + return rsock_sockopt_new(AF_INET, IPPROTO_IP, IP_MULTICAST_TTL, + rb_str_new((char*)&i, sizeof(i))); +#else +# error IPPROTO_IP or IP_MULTICAST_TTL is not implemented +#endif +} + +/* + * call-seq: + * sockopt.ip_multicast_ttl => integer + * + * Returns the ip_multicast_ttl data in _sockopt_ as a integer. + * + * sockopt = Socket::Option.ip_multicast_ttl(10) + * p sockopt.ip_multicast_ttl => 10 + */ +static VALUE +sockopt_ip_multicast_ttl(VALUE self) +{ + int family = NUM2INT(sockopt_family_m(self)); + int level = sockopt_level(self); + int optname = sockopt_optname(self); + +#if defined(IPPROTO_IP) && defined(IP_MULTICAST_TTL) + if (family == AF_INET && level == IPPROTO_IP && optname == IP_MULTICAST_TTL) { +# ifdef __NetBSD__ + return sockopt_byte(self); +# else + return sockopt_int(self); +# endif + } +/* + defined(IP_MULTICAST_LOOP) + */ +#endif + rb_raise(rb_eTypeError, "ip_multicast_ttl socket option expected"); + UNREACHABLE; +} + +#ifdef __NetBSD__ +# define inspect_ip_multicast_ttl(a,b,c,d) inspect_byte(a,b,c,d) +#else +# define inspect_ip_multicast_ttl(a,b,c,d) inspect_int(a,b,c,d) +#endif + static int inspect_int(int level, int optname, VALUE data, VALUE ret) { @@ -309,6 +485,18 @@ inspect_int(int level, int optname, VALU https://github.com/ruby/ruby/blob/trunk/ext/socket/option.c#L485 } static int +inspect_byte(int level, int optname, VALUE data, VALUE ret) +{ + if (RSTRING_LEN(data) == sizeof(unsigned char)) { + rb_str_catf(ret, " %d", (unsigned char)*RSTRING_PTR(data)); + return 1; + } + else { + return 0; + } +} + +static int inspect_errno(int level, int optname, VALUE data, VALUE ret) { if (RSTRING_LEN(data) == sizeof(int)) { @@ -805,6 +993,12 @@ sockopt_inspect(VALUE self) https://github.com/ruby/ruby/blob/trunk/ext/socket/option.c#L993 # if defined(IP_DROP_MEMBERSHIP) /* 4.4BSD, GNU/Linux */ case IP_DROP_MEMBERSHIP: inspected = inspect_ipv4_add_drop_membership(level, optname, data, ret); break; # endif +# if defined(IP_MULTICAST_LOOP) /* 4.4BSD, GNU/Linux */ + case IP_MULTICAST_LOOP: inspected = inspect_ip_multicast_loop(level, optname, data, ret); break; +# endif +# if defined(IP_MULTICAST_TTL) /* 4.4BSD, GNU/Linux */ + case IP_MULTICAST_TTL: inspected = inspect_ip_multicast_ttl(level, optname, data, ret); break; +# endif } break; # endif @@ -912,12 +1106,21 @@ rsock_init_sockopt(void) https://github.com/ruby/ruby/blob/trunk/ext/socket/option.c#L1106 rb_define_singleton_method(rb_cSockOpt, "int", sockopt_s_int, 4); rb_define_method(rb_cSockOpt, "int", sockopt_int, 0); + rb_define_singleton_method(rb_cSockOpt, "byte", sockopt_s_byte, 4); + rb_define_method(rb_cSockOpt, "byte", sockopt_byte, 0); + rb_define_singleton_method(rb_cSockOpt, "bool", sockopt_s_bool, 4); rb_define_method(rb_cSockOpt, "bool", sockopt_bool, 0); rb_define_singleton_method(rb_cSockOpt, "linger", sockopt_s_linger, 2); rb_define_method(rb_cSockOpt, "linger", sockopt_linger, 0); + rb_define_singleton_method(rb_cSockOpt, "ip_multicast_ttl", sockopt_s_ip_multicast_ttl, 1); + rb_define_method(rb_cSockOpt, "ip_multicast_ttl", sockopt_ip_multicast_ttl, 0); + + rb_define_singleton_method(rb_cSockOpt, "ip_multicast_loop", sockopt_s_ip_multicast_loop, 1); + rb_define_method(rb_cSockOpt, "ip_multicast_loop", sockopt_ip_multicast_loop, 0); + rb_define_method(rb_cSockOpt, "unpack", sockopt_unpack, 1); rb_define_method(rb_cSockOpt, "to_s", sockopt_data, 0); /* compatibility for ruby before 1.9.2 */ Index: test/socket/test_sockopt.rb =================================================================== --- test/socket/test_sockopt.rb (revision 41008) +++ test/socket/test_sockopt.rb (revision 41009) @@ -25,6 +25,24 @@ class TestSocketOption < Test::Unit::Tes https://github.com/ruby/ruby/blob/trunk/test/socket/test_sockopt.rb#L25 assert_equal(true, opt.bool) end + def test_ip_multicast_loop + sockopt = Socket::Option.ip_multicast_loop(128) + assert_equal('#<Socket::Option: INET IP MULTICAST_LOOP 128>', sockopt.inspect) + assert_equal(Socket::AF_INET, sockopt.family) + assert_equal(Socket::IPPROTO_IP, sockopt.level) + assert_equal(Socket::IP_MULTICAST_LOOP, sockopt.optname) + assert_equal(128, sockopt.ip_multicast_loop) + end + + def test_ip_multicast_ttl + sockopt = Socket::Option.ip_multicast_ttl(128) + assert_equal('#<Socket::Option: INET IP MULTICAST_TTL 128>', sockopt.inspect) + assert_equal(Socket::AF_INET, sockopt.family) + assert_equal(Socket::IPPROTO_IP, sockopt.level) + assert_equal(Socket::IP_MULTICAST_TTL, sockopt.optname) + assert_equal(128, sockopt.ip_multicast_ttl) + end + def test_unpack sockopt = Socket::Option.new(:INET, :SOCKET, :KEEPALIVE, [1].pack("i")) assert_equal([1], sockopt.unpack("i")) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/