Feature #6583 » socket.improve_bind_error.patch
ext/socket/udpsocket.c (working copy) | ||
---|---|---|
static VALUE
|
||
udp_bind(VALUE sock, VALUE host, VALUE port)
|
||
{
|
||
VALUE mesg;
|
||
rb_io_t *fptr;
|
||
struct addrinfo *res0, *res;
|
||
... | ... | |
return INT2FIX(0);
|
||
}
|
||
freeaddrinfo(res0);
|
||
rb_sys_fail("bind(2)");
|
||
port = rb_String(port);
|
||
mesg = rb_sprintf("bind(2) for \"%s\" port %s",
|
||
StringValueCStr(host),
|
||
StringValueCStr(port));
|
||
rb_sys_fail_str(mesg);
|
||
return INT2FIX(0);
|
||
}
|
||
ext/socket/ipsocket.c (working copy) | ||
---|---|---|
{
|
||
int type = arg->type;
|
||
struct addrinfo *res;
|
||
int fd, status = 0;
|
||
int fd, status = 0, local = 0;
|
||
const char *syscall = 0;
|
||
arg->remote.res = rsock_addrinfo(arg->remote.host, arg->remote.serv, SOCK_STREAM,
|
||
... | ... | |
else {
|
||
if (arg->local.res) {
|
||
status = bind(fd, arg->local.res->ai_addr, arg->local.res->ai_addrlen);
|
||
local = status;
|
||
syscall = "bind(2)";
|
||
}
|
||
... | ... | |
break;
|
||
}
|
||
if (status < 0) {
|
||
rb_sys_fail(syscall);
|
||
VALUE host, port, mesg;
|
||
const char * local_mesg;
|
||
if (local < 0) {
|
||
host = arg->local.host;
|
||
port = rb_String(arg->local.serv);
|
||
local_mesg = " (local address)";
|
||
} else {
|
||
host = arg->remote.host;
|
||
port = rb_String(arg->remote.serv);
|
||
local_mesg = "";
|
||
}
|
||
mesg = rb_sprintf("%s for \"%s\" port %s%s",
|
||
syscall, StringValuePtr(host), StringValuePtr(port),
|
||
local_mesg);
|
||
rb_sys_fail_str(mesg);
|
||
}
|
||
arg->fd = -1;
|
ext/socket/socket.c (working copy) | ||
---|---|---|
#include "rubysocket.h"
|
||
static VALUE sock_s_unpack_sockaddr_in(VALUE, VALUE);
|
||
static void
|
||
setup_domain_and_type(VALUE domain, int *dv, VALUE type, int *tv)
|
||
{
|
||
... | ... | |
SockAddrStringValue(addr);
|
||
GetOpenFile(sock, fptr);
|
||
if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_LENINT(addr)) < 0)
|
||
rb_sys_fail("bind(2)");
|
||
if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_LENINT(addr)) < 0) {
|
||
VALUE host_port = sock_s_unpack_sockaddr_in(sock, addr);
|
||
VALUE mesg = rb_sprintf("bind(2) for \"%s\" port %d",
|
||
StringValueCStr(RARRAY_PTR(host_port)[1]),
|
||
NUM2INT(RARRAY_PTR(host_port)[0]));
|
||
rb_sys_fail_str(mesg);
|
||
}
|
||
return INT2FIX(0);
|
||
}
|
test/socket/test_tcp.rb (working copy) | ||
---|---|---|
class TestSocket_TCPSocket < Test::Unit::TestCase
|
||
def test_initialize_failure
|
||
s = TCPServer.new("localhost", nil)
|
||
server_port = s.addr[1]
|
||
c = TCPSocket.new("localhost", server_port)
|
||
client_port = c.addr[1]
|
||
begin
|
||
# TCPServer.new uses SO_REUSEADDR so we must create a failure on the
|
||
# local address.
|
||
TCPSocket.new("localhost", server_port, "localhost", client_port)
|
||
flunk "expected SystemCallError"
|
||
rescue SystemCallError => e
|
||
assert_match "for \"localhost\" port #{client_port}", e.message
|
||
end
|
||
end
|
||
def test_recvfrom
|
||
svr = TCPServer.new("localhost", 0)
|
||
th = Thread.new {
|
test/socket/test_socket.rb (working copy) | ||
---|---|---|
}
|
||
end
|
||
def test_bind
|
||
Socket.open(Socket::AF_INET, Socket::SOCK_STREAM, 0) {|bound|
|
||
bound.bind(Socket.sockaddr_in(0, "127.0.0.1"))
|
||
addr = bound.getsockname
|
||
port, = Socket.unpack_sockaddr_in(addr)
|
||
Socket.open(Socket::AF_INET, Socket::SOCK_STREAM, 0) {|s|
|
||
e = assert_raises(Errno::EADDRINUSE) do
|
||
s.bind(Socket.sockaddr_in(port, "127.0.0.1"))
|
||
end
|
||
assert_match "bind(2) for \"127.0.0.1\" port #{port}", e.message
|
||
}
|
||
}
|
||
end
|
||
def test_getaddrinfo
|
||
# This should not send a DNS query because AF_UNIX.
|
||
assert_raise(SocketError) { Socket.getaddrinfo("www.kame.net", 80, "AF_UNIX") }
|
test/socket/test_udp.rb (working copy) | ||
---|---|---|
s.bind(host, 2000)
|
||
}
|
||
end
|
||
def test_bind_addrinuse
|
||
host = "127.0.0.1"
|
||
port = 2001
|
||
in_use = UDPSocket.new
|
||
in_use.bind(host, port)
|
||
s = UDPSocket.new
|
||
|
||
e = assert_raises(Errno::EADDRINUSE) do
|
||
s.bind(host, port)
|
||
end
|
||
assert_match "bind(2) for \"#{host}\" port #{port}", e.message
|
||
end
|
||
end if defined?(UDPSocket)
|