[ruby-dev:47907] Re: [ruby-cvs:51792] nobu:r44647 (trunk): socket/option.c: socket option variations

From: Nobuyoshi Nakada <nobu@...>
Date: 2014-01-19 09:12:38 UTC
List: ruby-dev #47907
(2014/01/19 16:48), Tanaka Akira wrote:
> 2014年1月19日 16:20 Nobuyoshi Nakada <nobu@ruby-lang.org>:
>>> これですけど、NUM2SOCKOPT などという名前はよろしくないと思います。
>>> この、NetBSD と OpenBSD で型が違うというのは、
>>> すべての socket option について成り立つものではないので。
>>
>> なるほど。じゃあsockoptじゃなくてmulticastoptとかでどうでしょう。
> 
> multicast のオプションにもいろいろあって、かならずしも
> NetBSD と OpenBSD では unsigned char, 他では int とは限りません。
> たとえば、IP_ADD_MEMBERSHIP は違います。
> 
> ちゃんとオプションの名前まで含めないとやっていることを表現できないんじゃないかなぁ。

じゃぁ、方針を変えてこれではどうでしょう。


diff --git a/ext/socket/option.c b/ext/socket/option.c
index dbed7d9..c62ebc9 100644
--- a/ext/socket/option.c
+++ b/ext/socket/option.c
@@ -2,15 +2,21 @@
 
 VALUE rb_cSockOpt;
 
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-typedef unsigned char rb_sockopt_t;
-# define NUM2SOCKOPT(value) NUM2CHR(rb_to_int(value))
-# define sockopt_value(obj) sockopt_byte(obj)
-# else
-typedef int rb_sockopt_t;
-# define NUM2SOCKOPT(value) NUM2INT(rb_to_int(value))
-# define sockopt_value(obj) sockopt_int(obj)
-#endif
+#define var_to_value(v) rb_str_new((const char *)&(v), sizeof(v))
+
+static VALUE
+sockopt_byte_to_value(VALUE value)
+{
+    char i = (unsigned char)NUM2CHR(rb_to_int(value));
+    return var_to_value(i);
+}
+
+static VALUE
+sockopt_int_to_value(VALUE value)
+{
+    int i = NUM2INT(rb_to_int(value));
+    return var_to_value(i);
+}
 
 static VALUE
 constant_to_sym(int constant, ID (*intern_const)(int))
@@ -167,8 +173,7 @@ sockopt_s_byte(VALUE klass, VALUE vfamily, VALUE vlevel, VALUE voptname, VALUE v
     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)));
+    return rsock_sockopt_new(family, level, optname, sockopt_byte_to_value(vint));
 }
 
 /*
@@ -209,8 +214,7 @@ sockopt_s_int(VALUE klass, VALUE vfamily, VALUE vlevel, VALUE voptname, VALUE vi
     int family = rsock_family_arg(vfamily);
     int level = rsock_level_arg(family, vlevel);
     int optname = rsock_optname_arg(family, level, voptname);
-    int i = NUM2INT(vint);
-    return rsock_sockopt_new(family, level, optname, rb_str_new((char*)&i, sizeof(i)));
+    return rsock_sockopt_new(family, level, optname, sockopt_int_to_value(vint));
 }
 
 /*
@@ -363,9 +367,13 @@ static VALUE
 sockopt_s_ipv4_multicast_loop(VALUE klass, VALUE value)
 {
 #if defined(IPPROTO_IP) && defined(IP_MULTICAST_LOOP)
-    rb_sockopt_t i = NUM2SOCKOPT(value);
+# if defined(__NetBSD__) || defined(__OpenBSD__)
+    VALUE o = sockopt_byte_to_value(value);
+# else
+    VALUE o = sockopt_int_to_value(value);
+# endif
     return rsock_sockopt_new(AF_INET, IPPROTO_IP, IP_MULTICAST_LOOP,
-	    rb_str_new((char*)&i, sizeof(i)));
+			     o);
 #else
 # error IPPROTO_IP or IP_MULTICAST_LOOP is not implemented
 #endif
@@ -418,9 +426,13 @@ static VALUE
 sockopt_s_ipv4_multicast_ttl(VALUE klass, VALUE value)
 {
 #if defined(IPPROTO_IP) && defined(IP_MULTICAST_TTL)
-    rb_sockopt_t i = NUM2SOCKOPT(value);
+# if defined(__NetBSD__) || defined(__OpenBSD__)
+    VALUE o = sockopt_byte_to_value(value);
+# else
+    VALUE o = sockopt_int_to_value(value);
+# endif
     return rsock_sockopt_new(AF_INET, IPPROTO_IP, IP_MULTICAST_TTL,
-	    rb_str_new((char*)&i, sizeof(i)));
+			     o);
 #else
 # error IPPROTO_IP or IP_MULTICAST_TTL is not implemented
 #endif

-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread