mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/socket/rubysocket.h (cmsg_type_arg): declared.
(Init_ancdata): ditto. * ext/socket/init.c (Init_socket_init): call Init_ancdata. * ext/socket/constants.c (cmsg_type_arg): defined. * ext/socket/depend: add dependency for ancdata.o. * ext/socket/mkconstants.rb: generate scm_optname_to_int. more constants. * ext/socket/extconf.rb: add ancdata.o. * ext/socket/ancdata.c: new file. new method BasicSocket#{sendmsg,sendmsg_nonblock,recvmsg,recvmsg_nonblock} git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@21943 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
c618d018d8
commit
61fc0c6cf4
10 changed files with 1259 additions and 0 deletions
19
ChangeLog
19
ChangeLog
|
@ -1,3 +1,22 @@
|
||||||
|
Mon Feb 2 11:45:10 2009 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* ext/socket/rubysocket.h (cmsg_type_arg): declared.
|
||||||
|
(Init_ancdata): ditto.
|
||||||
|
|
||||||
|
* ext/socket/init.c (Init_socket_init): call Init_ancdata.
|
||||||
|
|
||||||
|
* ext/socket/constants.c (cmsg_type_arg): defined.
|
||||||
|
|
||||||
|
* ext/socket/depend: add dependency for ancdata.o.
|
||||||
|
|
||||||
|
* ext/socket/mkconstants.rb: generate scm_optname_to_int.
|
||||||
|
more constants.
|
||||||
|
|
||||||
|
* ext/socket/extconf.rb: add ancdata.o.
|
||||||
|
|
||||||
|
* ext/socket/ancdata.c: new file. new method
|
||||||
|
BasicSocket#{sendmsg,sendmsg_nonblock,recvmsg,recvmsg_nonblock}
|
||||||
|
|
||||||
Mon Feb 2 10:57:27 2009 NAKAMURA Usaku <usa@ruby-lang.org>
|
Mon Feb 2 10:57:27 2009 NAKAMURA Usaku <usa@ruby-lang.org>
|
||||||
|
|
||||||
* win32/win32.c (open_dir_handle, rb_w32_opendir, move_to_next_entry,
|
* win32/win32.c (open_dir_handle, rb_w32_opendir, move_to_next_entry,
|
||||||
|
|
|
@ -21,6 +21,7 @@ socket/unixsocket.c
|
||||||
socket/unixserver.c
|
socket/unixserver.c
|
||||||
socket/socket.c
|
socket/socket.c
|
||||||
socket/option.c
|
socket/option.c
|
||||||
|
socket/ancdata.c
|
||||||
socket/constants.c
|
socket/constants.c
|
||||||
socket/lib/socket.rb
|
socket/lib/socket.rb
|
||||||
stringio/stringio.c
|
stringio/stringio.c
|
||||||
|
|
1070
ext/socket/ancdata.c
Normal file
1070
ext/socket/ancdata.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -92,6 +92,25 @@ shutdown_how_arg(VALUE how)
|
||||||
return constant_arg(how, shutdown_how_to_int, "unknown shutdown argument");
|
return constant_arg(how, shutdown_how_to_int, "unknown shutdown argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
cmsg_type_arg(int level, VALUE optname)
|
||||||
|
{
|
||||||
|
switch (level) {
|
||||||
|
case SOL_SOCKET:
|
||||||
|
return constant_arg(optname, scm_optname_to_int, "unknown UNIX control message");
|
||||||
|
case IPPROTO_IP:
|
||||||
|
return constant_arg(optname, ip_optname_to_int, "unknown IP control message");
|
||||||
|
case IPPROTO_IPV6:
|
||||||
|
return constant_arg(optname, ipv6_optname_to_int, "unknown IPv6 control message");
|
||||||
|
case IPPROTO_TCP:
|
||||||
|
return constant_arg(optname, tcp_optname_to_int, "unknown TCP control message");
|
||||||
|
case IPPROTO_UDP:
|
||||||
|
return constant_arg(optname, udp_optname_to_int, "unknown UDP control message");
|
||||||
|
default:
|
||||||
|
return NUM2INT(optname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sock_define_const(const char *name, int value, VALUE mConst)
|
sock_define_const(const char *name, int value, VALUE mConst)
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,6 +14,7 @@ udpsocket.o: udpsocket.c $(SOCK_HEADERS)
|
||||||
unixsocket.o: unixsocket.c $(SOCK_HEADERS)
|
unixsocket.o: unixsocket.c $(SOCK_HEADERS)
|
||||||
unixserver.o: unixserver.c $(SOCK_HEADERS)
|
unixserver.o: unixserver.c $(SOCK_HEADERS)
|
||||||
option.o: option.c $(SOCK_HEADERS)
|
option.o: option.c $(SOCK_HEADERS)
|
||||||
|
ancdata.o: ancdata.c $(SOCK_HEADERS)
|
||||||
raddrinfo.o: raddrinfo.c $(SOCK_HEADERS)
|
raddrinfo.o: raddrinfo.c $(SOCK_HEADERS)
|
||||||
|
|
||||||
getnameinfo.o: getnameinfo.c $(arch_hdrdir)/ruby/config.h addrinfo.h sockport.h
|
getnameinfo.o: getnameinfo.c $(arch_hdrdir)/ruby/config.h addrinfo.h sockport.h
|
||||||
|
|
|
@ -255,6 +255,7 @@ $objs = [
|
||||||
"unixsocket.#{$OBJEXT}",
|
"unixsocket.#{$OBJEXT}",
|
||||||
"unixserver.#{$OBJEXT}",
|
"unixserver.#{$OBJEXT}",
|
||||||
"option.#{$OBJEXT}",
|
"option.#{$OBJEXT}",
|
||||||
|
"ancdata.#{$OBJEXT}",
|
||||||
"raddrinfo.#{$OBJEXT}"
|
"raddrinfo.#{$OBJEXT}"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -520,6 +520,7 @@ Init_socket_init()
|
||||||
Init_unixsocket();
|
Init_unixsocket();
|
||||||
Init_unixserver();
|
Init_unixserver();
|
||||||
Init_sockopt();
|
Init_sockopt();
|
||||||
|
Init_ancdata();
|
||||||
Init_addrinfo();
|
Init_addrinfo();
|
||||||
Init_socket_constants();
|
Init_socket_constants();
|
||||||
}
|
}
|
||||||
|
|
|
@ -249,6 +249,7 @@ def_name_to_int("ipv6_optname_to_int", /\AIPV6_/, "IPV6_", "IPPROTO_IPV6")
|
||||||
def_name_to_int("tcp_optname_to_int", /\ATCP_/, "TCP_")
|
def_name_to_int("tcp_optname_to_int", /\ATCP_/, "TCP_")
|
||||||
def_name_to_int("udp_optname_to_int", /\AUDP_/, "UDP_")
|
def_name_to_int("udp_optname_to_int", /\AUDP_/, "UDP_")
|
||||||
def_name_to_int("shutdown_how_to_int", /\ASHUT_/, "SHUT_")
|
def_name_to_int("shutdown_how_to_int", /\ASHUT_/, "SHUT_")
|
||||||
|
def_name_to_int("scm_optname_to_int", /\ASCM_/, "SCM_")
|
||||||
|
|
||||||
def_intern('intern_family', /\AAF_/)
|
def_intern('intern_family', /\AAF_/)
|
||||||
def_intern('intern_protocol_family', /\APF_/)
|
def_intern('intern_protocol_family', /\APF_/)
|
||||||
|
@ -482,6 +483,35 @@ IP_DROP_MEMBERSHIP
|
||||||
IP_DEFAULT_MULTICAST_TTL
|
IP_DEFAULT_MULTICAST_TTL
|
||||||
IP_DEFAULT_MULTICAST_LOOP
|
IP_DEFAULT_MULTICAST_LOOP
|
||||||
IP_MAX_MEMBERSHIPS
|
IP_MAX_MEMBERSHIPS
|
||||||
|
IP_ROUTER_ALERT
|
||||||
|
IP_PKTINFO
|
||||||
|
IP_PKTOPTIONS
|
||||||
|
IP_MTU_DISCOVER
|
||||||
|
IP_RECVERR
|
||||||
|
IP_RECVTOS
|
||||||
|
IP_MTU
|
||||||
|
IP_FREEBIND
|
||||||
|
IP_IPSEC_POLICY
|
||||||
|
IP_XFRM_POLICY
|
||||||
|
IP_PASSSEC
|
||||||
|
IP_PMTUDISC_DONT
|
||||||
|
IP_PMTUDISC_WANT
|
||||||
|
IP_PMTUDISC_DO
|
||||||
|
IP_UNBLOCK_SOURCE
|
||||||
|
IP_BLOCK_SOURCE
|
||||||
|
IP_ADD_SOURCE_MEMBERSHIP
|
||||||
|
IP_DROP_SOURCE_MEMBERSHIP
|
||||||
|
IP_MSFILTER
|
||||||
|
|
||||||
|
MCAST_JOIN_GROUP
|
||||||
|
MCAST_BLOCK_SOURCE
|
||||||
|
MCAST_UNBLOCK_SOURCE
|
||||||
|
MCAST_LEAVE_GROUP
|
||||||
|
MCAST_JOIN_SOURCE_GROUP
|
||||||
|
MCAST_LEAVE_SOURCE_GROUP
|
||||||
|
MCAST_MSFILTER
|
||||||
|
MCAST_EXCLUDE
|
||||||
|
MCAST_INCLUDE
|
||||||
|
|
||||||
SO_DEBUG
|
SO_DEBUG
|
||||||
SO_REUSEADDR
|
SO_REUSEADDR
|
||||||
|
@ -617,3 +647,6 @@ INET_ADDRSTRLEN
|
||||||
INET6_ADDRSTRLEN
|
INET6_ADDRSTRLEN
|
||||||
|
|
||||||
SOMAXCONN
|
SOMAXCONN
|
||||||
|
|
||||||
|
SCM_RIGHTS
|
||||||
|
SCM_CREDENTIALS
|
||||||
|
|
|
@ -190,6 +190,7 @@ int socktype_arg(VALUE type);
|
||||||
int level_arg(VALUE level);
|
int level_arg(VALUE level);
|
||||||
int optname_arg(int level, VALUE optname);
|
int optname_arg(int level, VALUE optname);
|
||||||
int shutdown_how_arg(VALUE how);
|
int shutdown_how_arg(VALUE how);
|
||||||
|
int cmsg_type_arg(int level, VALUE optname);
|
||||||
|
|
||||||
int rb_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);
|
int rb_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);
|
||||||
int rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags);
|
int rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags);
|
||||||
|
@ -254,6 +255,7 @@ void Init_udpsocket(void);
|
||||||
void Init_unixsocket(void);
|
void Init_unixsocket(void);
|
||||||
void Init_unixserver(void);
|
void Init_unixserver(void);
|
||||||
void Init_socket_constants(void);
|
void Init_socket_constants(void);
|
||||||
|
void Init_ancdata(void);
|
||||||
void Init_addrinfo(void);
|
void Init_addrinfo(void);
|
||||||
void Init_sockopt(void);
|
void Init_sockopt(void);
|
||||||
void Init_socket_init(void);
|
void Init_socket_init(void);
|
||||||
|
|
|
@ -31,6 +31,118 @@ class TestUNIXSocket < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_fd_passing_n
|
||||||
|
io_ary = []
|
||||||
|
return if !defined?(Socket::SCM_RIGHTS)
|
||||||
|
io_ary.concat IO.pipe
|
||||||
|
io_ary.concat IO.pipe
|
||||||
|
io_ary.concat IO.pipe
|
||||||
|
send_io_ary = []
|
||||||
|
io_ary.each {|io|
|
||||||
|
send_io_ary << io
|
||||||
|
UNIXSocket.pair {|s1, s2|
|
||||||
|
begin
|
||||||
|
ret = s1.sendmsg("\0", 0, nil, [Socket::SOL_SOCKET, Socket::SCM_RIGHTS,
|
||||||
|
send_io_ary.map {|io| io.fileno }.pack("i!*")])
|
||||||
|
rescue NotImplementedError
|
||||||
|
return
|
||||||
|
end
|
||||||
|
assert_equal(1, ret)
|
||||||
|
ret = s2.recvmsg
|
||||||
|
data, srcaddr, flags, *ctls = ret
|
||||||
|
recv_io_ary = []
|
||||||
|
ctls.each {|ctl|
|
||||||
|
next if ctl.level != Socket::SOL_SOCKET || ctl.type != Socket::SCM_RIGHTS
|
||||||
|
recv_io_ary.concat ctl.data.unpack("i!*").map {|fd| IO.new(fd) }
|
||||||
|
}
|
||||||
|
assert_equal(send_io_ary.length, recv_io_ary.length)
|
||||||
|
send_io_ary.length.times {|i|
|
||||||
|
assert_not_equal(send_io_ary[i].fileno, recv_io_ary[i].fileno)
|
||||||
|
assert(File.identical?(send_io_ary[i], recv_io_ary[i]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ensure
|
||||||
|
io_ary.each {|io| io.close if !io.closed? }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_sendmsg
|
||||||
|
return if !defined?(Socket::SCM_RIGHTS)
|
||||||
|
IO.pipe {|r1, w|
|
||||||
|
UNIXSocket.pair {|s1, s2|
|
||||||
|
begin
|
||||||
|
ret = s1.sendmsg("\0", 0, nil, [Socket::SOL_SOCKET, Socket::SCM_RIGHTS, [r1.fileno].pack("i!")])
|
||||||
|
rescue NotImplementedError
|
||||||
|
return
|
||||||
|
end
|
||||||
|
assert_equal(1, ret)
|
||||||
|
r2 = s2.recv_io
|
||||||
|
begin
|
||||||
|
assert(File.identical?(r1, r2))
|
||||||
|
ensure
|
||||||
|
r2.close
|
||||||
|
end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_sendmsg_ancillarydata
|
||||||
|
return if !defined?(Socket::SCM_RIGHTS)
|
||||||
|
return if !defined?(Socket::AncillaryData)
|
||||||
|
IO.pipe {|r1, w|
|
||||||
|
UNIXSocket.pair {|s1, s2|
|
||||||
|
begin
|
||||||
|
ad = Socket::AncillaryData.int(:SOCKET, :RIGHTS, r1.fileno)
|
||||||
|
ret = s1.sendmsg("\0", 0, nil, ad)
|
||||||
|
rescue NotImplementedError
|
||||||
|
return
|
||||||
|
end
|
||||||
|
assert_equal(1, ret)
|
||||||
|
r2 = s2.recv_io
|
||||||
|
begin
|
||||||
|
assert(File.identical?(r1, r2))
|
||||||
|
ensure
|
||||||
|
r2.close
|
||||||
|
end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_recvmsg
|
||||||
|
return if !defined?(Socket::SCM_RIGHTS)
|
||||||
|
IO.pipe {|r1, w|
|
||||||
|
UNIXSocket.pair {|s1, s2|
|
||||||
|
s1.send_io(r1)
|
||||||
|
ret = s2.recvmsg
|
||||||
|
data, srcaddr, flags, *ctls = ret
|
||||||
|
assert_equal("\0", data)
|
||||||
|
if flags == nil
|
||||||
|
# struct msghdr is 4.3BSD style (msg_accrights field).
|
||||||
|
assert_instance_of(Array, ctls)
|
||||||
|
assert_equal(0, ctls.length)
|
||||||
|
else
|
||||||
|
# struct msghdr is POSIX/4.4BSD style (msg_control field).
|
||||||
|
assert_equal(0, flags & (Socket::MSG_TRUNC|Socket::MSG_CTRUNC))
|
||||||
|
assert_instance_of(AddrInfo, srcaddr)
|
||||||
|
assert_instance_of(Array, ctls)
|
||||||
|
assert_equal(1, ctls.length)
|
||||||
|
assert_instance_of(Socket::AncillaryData, ctls[0])
|
||||||
|
assert_equal(Socket::SOL_SOCKET, ctls[0].level)
|
||||||
|
assert_equal(Socket::SCM_RIGHTS, ctls[0].type)
|
||||||
|
assert_instance_of(String, ctls[0].data)
|
||||||
|
fd, rest = ctls[0].data.unpack("i!a*")
|
||||||
|
assert_equal("", rest)
|
||||||
|
r2 = IO.new(fd)
|
||||||
|
begin
|
||||||
|
assert(File.identical?(r1, r2))
|
||||||
|
ensure
|
||||||
|
r2.close
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
def bound_unix_socket(klass)
|
def bound_unix_socket(klass)
|
||||||
tmpfile = Tempfile.new("testrubysock")
|
tmpfile = Tempfile.new("testrubysock")
|
||||||
path = tmpfile.path
|
path = tmpfile.path
|
||||||
|
|
Loading…
Reference in a new issue