mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/socket/rubysocket.h (sockopt_new): add family argument.
* ext/socket/option.c (sockopt_initialize): add vfamily argument. (sockopt_new): add family argument and record it in the object. (sockopt_family): new method. (sockopt_s_int): add vfamily argument. (sockopt_inspect): show family. * ext/socket/basicsocket.c (bsock_getsockopt): check address family using getsockname. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22135 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
3e11901f1c
commit
c02ce88762
4 changed files with 63 additions and 16 deletions
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
||||||
|
Mon Feb 9 00:01:47 2009 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* ext/socket/rubysocket.h (sockopt_new): add family argument.
|
||||||
|
|
||||||
|
* ext/socket/option.c (sockopt_initialize): add vfamily argument.
|
||||||
|
(sockopt_new): add family argument and record it in the object.
|
||||||
|
(sockopt_family): new method.
|
||||||
|
(sockopt_s_int): add vfamily argument.
|
||||||
|
(sockopt_inspect): show family.
|
||||||
|
|
||||||
|
* ext/socket/basicsocket.c (bsock_getsockopt): check address family
|
||||||
|
using getsockname.
|
||||||
|
|
||||||
Sun Feb 8 23:37:17 2009 Yusuke Endoh <mame@tsg.ne.jp>
|
Sun Feb 8 23:37:17 2009 Yusuke Endoh <mame@tsg.ne.jp>
|
||||||
|
|
||||||
* enumerator.c (enumerator_with_index): receives one argument which
|
* enumerator.c (enumerator_with_index): receives one argument which
|
||||||
|
|
|
@ -290,6 +290,8 @@ bsock_getsockopt(VALUE sock, VALUE lev, VALUE optname)
|
||||||
socklen_t len;
|
socklen_t len;
|
||||||
char *buf;
|
char *buf;
|
||||||
rb_io_t *fptr;
|
rb_io_t *fptr;
|
||||||
|
struct sockaddr_storage ss;
|
||||||
|
socklen_t sslen = sizeof(ss);
|
||||||
|
|
||||||
level = level_arg(lev);
|
level = level_arg(lev);
|
||||||
option = optname_arg(level, optname);
|
option = optname_arg(level, optname);
|
||||||
|
@ -297,10 +299,16 @@ bsock_getsockopt(VALUE sock, VALUE lev, VALUE optname)
|
||||||
buf = ALLOCA_N(char,len);
|
buf = ALLOCA_N(char,len);
|
||||||
|
|
||||||
GetOpenFile(sock, fptr);
|
GetOpenFile(sock, fptr);
|
||||||
|
|
||||||
|
if (getsockname(fptr->fd, (struct sockaddr*)&ss, &sslen) < 0)
|
||||||
|
rb_sys_fail("getsockname(2)");
|
||||||
|
|
||||||
if (getsockopt(fptr->fd, level, option, buf, &len) < 0)
|
if (getsockopt(fptr->fd, level, option, buf, &len) < 0)
|
||||||
rb_sys_fail_path(fptr->pathv);
|
rb_sys_fail_path(fptr->pathv);
|
||||||
|
|
||||||
return sockopt_new(level, option, rb_str_new(buf, len));
|
if (sslen < (char*)&ss.ss_family + sizeof(ss.ss_family) - (char*)&ss)
|
||||||
|
ss.ss_family = AF_UNSPEC;
|
||||||
|
return sockopt_new(ss.ss_family, level, option, rb_str_new(buf, len));
|
||||||
#else
|
#else
|
||||||
rb_notimplement();
|
rb_notimplement();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -35,11 +35,14 @@ optname_to_sym(int level, int optname)
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
sockopt_initialize(VALUE self, VALUE vlevel, VALUE voptname, VALUE data)
|
sockopt_initialize(VALUE self, VALUE vfamily, VALUE vlevel, VALUE voptname, VALUE data)
|
||||||
{
|
{
|
||||||
|
int family;
|
||||||
int level;
|
int level;
|
||||||
StringValue(data);
|
StringValue(data);
|
||||||
level = level_arg(vlevel);
|
level = level_arg(vlevel);
|
||||||
|
family = family_arg(vfamily);
|
||||||
|
rb_ivar_set(self, rb_intern("family"), INT2NUM(family));
|
||||||
rb_ivar_set(self, rb_intern("level"), INT2NUM(level));
|
rb_ivar_set(self, rb_intern("level"), INT2NUM(level));
|
||||||
rb_ivar_set(self, rb_intern("optname"), INT2NUM(optname_arg(level, voptname)));
|
rb_ivar_set(self, rb_intern("optname"), INT2NUM(optname_arg(level, voptname)));
|
||||||
rb_ivar_set(self, rb_intern("data"), data);
|
rb_ivar_set(self, rb_intern("data"), data);
|
||||||
|
@ -47,22 +50,36 @@ sockopt_initialize(VALUE self, VALUE vlevel, VALUE voptname, VALUE data)
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
sockopt_new(int level, int optname, VALUE data)
|
sockopt_new(int family, int level, int optname, VALUE data)
|
||||||
{
|
{
|
||||||
NEWOBJ(obj, struct RObject);
|
NEWOBJ(obj, struct RObject);
|
||||||
OBJSETUP(obj, rb_cSockOpt, T_OBJECT);
|
OBJSETUP(obj, rb_cSockOpt, T_OBJECT);
|
||||||
StringValue(data);
|
StringValue(data);
|
||||||
sockopt_initialize((VALUE)obj, INT2NUM(level), INT2NUM(optname), data);
|
sockopt_initialize((VALUE)obj, INT2NUM(family), INT2NUM(level), INT2NUM(optname), data);
|
||||||
return (VALUE)obj;
|
return (VALUE)obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* sockopt.family => integer
|
||||||
|
*
|
||||||
|
* returns the socket family as an integer.
|
||||||
|
*
|
||||||
|
* p Socket::Option.new(:INET6, :IPV6, :RECVPKTINFO, [1].pack("i!")).family
|
||||||
|
*/
|
||||||
|
static VALUE
|
||||||
|
sockopt_family(VALUE self)
|
||||||
|
{
|
||||||
|
return rb_attr_get(self, rb_intern("family"));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* sockopt.level => integer
|
* sockopt.level => integer
|
||||||
*
|
*
|
||||||
* returns the socket level as an integer.
|
* returns the socket level as an integer.
|
||||||
*
|
*
|
||||||
* p Socket::Option.new(:IPV6, :RECVPKTINFO, [1].pack("i!")).level
|
* p Socket::Option.new(:INET6, :IPV6, :RECVPKTINFO, [1].pack("i!")).level
|
||||||
*/
|
*/
|
||||||
static VALUE
|
static VALUE
|
||||||
sockopt_level(VALUE self)
|
sockopt_level(VALUE self)
|
||||||
|
@ -76,7 +93,7 @@ sockopt_level(VALUE self)
|
||||||
*
|
*
|
||||||
* returns the socket option name as an integer.
|
* returns the socket option name as an integer.
|
||||||
*
|
*
|
||||||
* p Socket::Option.new(:IPV6, :RECVPKTINFO, [1].pack("i!")).optname
|
* p Socket::Option.new(:INET6, :IPV6, :RECVPKTINFO, [1].pack("i!")).optname
|
||||||
*/
|
*/
|
||||||
static VALUE
|
static VALUE
|
||||||
sockopt_optname(VALUE self)
|
sockopt_optname(VALUE self)
|
||||||
|
@ -90,7 +107,7 @@ sockopt_optname(VALUE self)
|
||||||
*
|
*
|
||||||
* returns the socket option data as a string.
|
* returns the socket option data as a string.
|
||||||
*
|
*
|
||||||
* p Socket::Option.new(:IPV6, :PKTINFO, [1].pack("i!")).data
|
* p Socket::Option.new(:INET6, :IPV6, :PKTINFO, [1].pack("i!")).data
|
||||||
*/
|
*/
|
||||||
static VALUE
|
static VALUE
|
||||||
sockopt_data(VALUE self)
|
sockopt_data(VALUE self)
|
||||||
|
@ -100,7 +117,7 @@ sockopt_data(VALUE self)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* Socket::Option.int(level, optname, integer) => sockopt
|
* Socket::Option.int(family, level, optname, integer) => sockopt
|
||||||
*
|
*
|
||||||
* Creates a new Socket::Option object which contains an int as data.
|
* Creates a new Socket::Option object which contains an int as data.
|
||||||
*
|
*
|
||||||
|
@ -110,12 +127,13 @@ sockopt_data(VALUE self)
|
||||||
* #=> #<Socket::Option: SOCKET KEEPALIVE 1>
|
* #=> #<Socket::Option: SOCKET KEEPALIVE 1>
|
||||||
*/
|
*/
|
||||||
static VALUE
|
static VALUE
|
||||||
sockopt_s_int(VALUE klass, VALUE vlevel, VALUE voptname, VALUE vint)
|
sockopt_s_int(VALUE klass, VALUE vfamily, VALUE vlevel, VALUE voptname, VALUE vint)
|
||||||
{
|
{
|
||||||
|
int family = family_arg(vfamily);
|
||||||
int level = level_arg(vlevel);
|
int level = level_arg(vlevel);
|
||||||
int optname = optname_arg(level, voptname);
|
int optname = optname_arg(level, voptname);
|
||||||
int i = NUM2INT(vint);
|
int i = NUM2INT(vint);
|
||||||
return sockopt_new(level, optname, rb_str_new((char*)&i, sizeof(i)));
|
return sockopt_new(family, level, optname, rb_str_new((char*)&i, sizeof(i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -241,21 +259,28 @@ inspect_peercred(int level, int optname, VALUE data, VALUE ret)
|
||||||
static VALUE
|
static VALUE
|
||||||
sockopt_inspect(VALUE self)
|
sockopt_inspect(VALUE self)
|
||||||
{
|
{
|
||||||
|
int family = NUM2INT(sockopt_family(self));
|
||||||
int level = NUM2INT(sockopt_level(self));
|
int level = NUM2INT(sockopt_level(self));
|
||||||
int optname = NUM2INT(sockopt_optname(self));
|
int optname = NUM2INT(sockopt_optname(self));
|
||||||
VALUE data = sockopt_data(self);
|
VALUE data = sockopt_data(self);
|
||||||
VALUE v, ret;
|
VALUE v, ret;
|
||||||
ID level_id;
|
ID family_id, level_id;
|
||||||
|
|
||||||
StringValue(data);
|
StringValue(data);
|
||||||
|
|
||||||
ret = rb_sprintf("#<%s: ", rb_obj_classname(self));
|
ret = rb_sprintf("#<%s: ", rb_obj_classname(self));
|
||||||
|
|
||||||
|
family_id = intern_family(family);
|
||||||
|
if (family_id)
|
||||||
|
rb_str_cat2(ret, rb_id2name(family_id));
|
||||||
|
else
|
||||||
|
rb_str_catf(ret, "family:%d", family);
|
||||||
|
|
||||||
level_id = intern_level(level);
|
level_id = intern_level(level);
|
||||||
if (level_id)
|
if (level_id)
|
||||||
rb_str_cat2(ret, rb_id2name(level_id));
|
rb_str_catf(ret, " %s", rb_id2name(level_id));
|
||||||
else
|
else
|
||||||
rb_str_catf(ret, "level:%d", level);
|
rb_str_catf(ret, " level:%d", level);
|
||||||
|
|
||||||
v = optname_to_sym(level, optname);
|
v = optname_to_sym(level, optname);
|
||||||
if (SYMBOL_P(v))
|
if (SYMBOL_P(v))
|
||||||
|
@ -381,13 +406,14 @@ void
|
||||||
Init_sockopt(void)
|
Init_sockopt(void)
|
||||||
{
|
{
|
||||||
rb_cSockOpt = rb_define_class_under(rb_cSocket, "Option", rb_cObject);
|
rb_cSockOpt = rb_define_class_under(rb_cSocket, "Option", rb_cObject);
|
||||||
rb_define_method(rb_cSockOpt, "initialize", sockopt_initialize, 3);
|
rb_define_method(rb_cSockOpt, "initialize", sockopt_initialize, 4);
|
||||||
|
rb_define_method(rb_cSockOpt, "family", sockopt_family, 0);
|
||||||
rb_define_method(rb_cSockOpt, "level", sockopt_level, 0);
|
rb_define_method(rb_cSockOpt, "level", sockopt_level, 0);
|
||||||
rb_define_method(rb_cSockOpt, "optname", sockopt_optname, 0);
|
rb_define_method(rb_cSockOpt, "optname", sockopt_optname, 0);
|
||||||
rb_define_method(rb_cSockOpt, "data", sockopt_data, 0);
|
rb_define_method(rb_cSockOpt, "data", sockopt_data, 0);
|
||||||
rb_define_method(rb_cSockOpt, "inspect", sockopt_inspect, 0);
|
rb_define_method(rb_cSockOpt, "inspect", sockopt_inspect, 0);
|
||||||
|
|
||||||
rb_define_singleton_method(rb_cSockOpt, "int", sockopt_s_int, 3);
|
rb_define_singleton_method(rb_cSockOpt, "int", sockopt_s_int, 4);
|
||||||
rb_define_method(rb_cSockOpt, "int", sockopt_int, 0);
|
rb_define_method(rb_cSockOpt, "int", sockopt_int, 0);
|
||||||
|
|
||||||
rb_define_method(rb_cSockOpt, "unpack", sockopt_unpack, 1);
|
rb_define_method(rb_cSockOpt, "unpack", sockopt_unpack, 1);
|
||||||
|
|
|
@ -244,7 +244,7 @@ VALUE sock_listen(VALUE sock, VALUE log);
|
||||||
VALUE s_accept(VALUE klass, int fd, struct sockaddr *sockaddr, socklen_t *len);
|
VALUE s_accept(VALUE klass, int fd, struct sockaddr *sockaddr, socklen_t *len);
|
||||||
VALUE s_accept_nonblock(VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len);
|
VALUE s_accept_nonblock(VALUE klass, rb_io_t *fptr, struct sockaddr *sockaddr, socklen_t *len);
|
||||||
|
|
||||||
VALUE sockopt_new(int level, int optname, VALUE data);
|
VALUE sockopt_new(int family, int level, int optname, VALUE data);
|
||||||
|
|
||||||
void Init_basicsocket(void);
|
void Init_basicsocket(void);
|
||||||
void Init_ipsocket(void);
|
void Init_ipsocket(void);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue