summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/socket/raddrinfo.c19
-rw-r--r--ext/socket/rubysocket.h8
-rw-r--r--ext/socket/socket.c46
3 files changed, 59 insertions, 14 deletions
diff --git a/ext/socket/raddrinfo.c b/ext/socket/raddrinfo.c
index 569456cae3..11d298011c 100644
--- a/ext/socket/raddrinfo.c
+++ b/ext/socket/raddrinfo.c
@@ -1158,8 +1158,8 @@ addrinfo_inspect(VALUE self)
* Addrinfo.unix("/tmp/sock").inspect_sockaddr #=> "/tmp/sock"
*
*/
-static VALUE
-addrinfo_inspect_sockaddr(VALUE self)
+VALUE
+rsock_addrinfo_inspect_sockaddr(VALUE self)
{
return inspect_sockaddr(self, rb_str_new("", 0));
}
@@ -2127,6 +2127,19 @@ rsock_sockaddr_string_value(volatile VALUE *v)
return *v;
}
+VALUE
+rsock_sockaddr_string_value_with_addrinfo(volatile VALUE *v, VALUE *rai_ret)
+{
+ VALUE val = *v;
+ *rai_ret = Qnil;
+ if (IS_ADDRINFO(val)) {
+ *v = addrinfo_to_sockaddr(val);
+ *rai_ret = val;
+ }
+ StringValue(*v);
+ return *v;
+}
+
char *
rsock_sockaddr_string_value_ptr(volatile VALUE *v)
{
@@ -2198,7 +2211,7 @@ rsock_init_addrinfo(void)
rb_define_alloc_func(rb_cAddrinfo, addrinfo_s_allocate);
rb_define_method(rb_cAddrinfo, "initialize", addrinfo_initialize, -1);
rb_define_method(rb_cAddrinfo, "inspect", addrinfo_inspect, 0);
- rb_define_method(rb_cAddrinfo, "inspect_sockaddr", addrinfo_inspect_sockaddr, 0);
+ rb_define_method(rb_cAddrinfo, "inspect_sockaddr", rsock_addrinfo_inspect_sockaddr, 0);
rb_define_singleton_method(rb_cAddrinfo, "getaddrinfo", addrinfo_s_getaddrinfo, -1);
rb_define_singleton_method(rb_cAddrinfo, "ip", addrinfo_s_ip, 1);
rb_define_singleton_method(rb_cAddrinfo, "tcp", addrinfo_s_tcp, 2);
diff --git a/ext/socket/rubysocket.h b/ext/socket/rubysocket.h
index 5dd742b98f..133276c934 100644
--- a/ext/socket/rubysocket.h
+++ b/ext/socket/rubysocket.h
@@ -227,8 +227,11 @@ int Rconnect();
#define SockAddrStringValue(v) rsock_sockaddr_string_value(&(v))
#define SockAddrStringValuePtr(v) rsock_sockaddr_string_value_ptr(&(v))
+#define SockAddrStringValueWithAddrinfo(v, rai_ret) rsock_sockaddr_string_value_with_addrinfo(&(v), &(rai_ret))
VALUE rsock_sockaddr_string_value(volatile VALUE *);
char *rsock_sockaddr_string_value_ptr(volatile VALUE *);
+VALUE rsock_sockaddr_string_value_with_addrinfo(volatile VALUE *v, VALUE *ai_ret);
+
VALUE rb_check_sockaddr_string_type(VALUE);
NORETURN(void rsock_raise_socket_error(const char *, int));
@@ -250,6 +253,7 @@ VALUE rsock_fd_socket_addrinfo(int fd, struct sockaddr *addr, socklen_t len);
VALUE rsock_io_socket_addrinfo(VALUE io, struct sockaddr *addr, socklen_t len);
VALUE rsock_addrinfo_new(struct sockaddr *addr, socklen_t len, int family, int socktype, int protocol, VALUE canonname, VALUE inspectname);
+VALUE rsock_addrinfo_inspect_sockaddr(VALUE rai);
VALUE rsock_make_ipaddr(struct sockaddr *addr, socklen_t addrlen);
VALUE rsock_ipaddr(struct sockaddr *sockaddr, socklen_t sockaddrlen, int norevlookup);
@@ -335,6 +339,8 @@ void rsock_init_socket_init(void);
NORETURN(void rsock_sys_fail_host_port(const char *, VALUE, VALUE));
NORETURN(void rsock_sys_fail_path(const char *, VALUE));
-NORETURN(void rsock_sys_fail_sockaddr(const char *, VALUE));
+NORETURN(void rsock_sys_fail_sockaddr(const char *, VALUE addr));
+NORETURN(void rsock_sys_fail_addrinfo(const char *, VALUE rai));
+NORETURN(void rsock_sys_fail_sockaddr_or_addrinfo(const char *, VALUE addr, VALUE rai));
#endif
diff --git a/ext/socket/socket.c b/ext/socket/socket.c
index f4d8b3f47e..d05e5a3e42 100644
--- a/ext/socket/socket.c
+++ b/ext/socket/socket.c
@@ -49,11 +49,34 @@ rsock_sys_fail_path(const char *mesg, VALUE path)
void
rsock_sys_fail_sockaddr(const char *mesg, VALUE addr)
{
- VALUE host_port = sock_s_unpack_sockaddr_in(rb_cSocket, addr);
+ VALUE rai;
- rsock_sys_fail_host_port(mesg,
- RARRAY_PTR(host_port)[1],
- RARRAY_PTR(host_port)[0]);
+ rai = rsock_addrinfo_new(
+ (struct sockaddr *)RSTRING_PTR(addr),
+ RSTRING_LEN(addr),
+ PF_UNSPEC, 0, 0, Qnil, Qnil);
+
+ rsock_sys_fail_addrinfo(mesg, rai);
+}
+
+void
+rsock_sys_fail_addrinfo(const char *mesg, VALUE rai)
+{
+ VALUE str, message;
+
+ str = rsock_addrinfo_inspect_sockaddr(rai);
+ message = rb_sprintf("%s for %s", mesg, StringValueCStr(str));
+
+ rb_sys_fail_str(message);
+}
+
+void
+rsock_sys_fail_addrinfo_or_sockaddr(const char *mesg, VALUE addr, VALUE rai)
+{
+ if (NIL_P(rai))
+ rsock_sys_fail_sockaddr(mesg, addr);
+ else
+ rsock_sys_fail_addrinfo(mesg, rai);
}
static void
@@ -350,16 +373,17 @@ rsock_sock_s_socketpair(int argc, VALUE *argv, VALUE klass)
static VALUE
sock_connect(VALUE sock, VALUE addr)
{
+ VALUE rai;
rb_io_t *fptr;
int fd, n;
- SockAddrStringValue(addr);
+ SockAddrStringValueWithAddrinfo(addr, rai);
addr = rb_str_new4(addr);
GetOpenFile(sock, fptr);
fd = fptr->fd;
n = rsock_connect(fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_LENINT(addr), 0);
if (n < 0) {
- rsock_sys_fail_sockaddr("connect(2)", addr);
+ rsock_sys_fail_addrinfo_or_sockaddr("connect(2)", addr, rai);
}
return INT2FIX(n);
@@ -410,10 +434,11 @@ sock_connect(VALUE sock, VALUE addr)
static VALUE
sock_connect_nonblock(VALUE sock, VALUE addr)
{
+ VALUE rai;
rb_io_t *fptr;
int n;
- SockAddrStringValue(addr);
+ SockAddrStringValueWithAddrinfo(addr, rai);
addr = rb_str_new4(addr);
GetOpenFile(sock, fptr);
rb_io_set_nonblock(fptr);
@@ -421,7 +446,7 @@ sock_connect_nonblock(VALUE sock, VALUE addr)
if (n < 0) {
if (errno == EINPROGRESS)
rb_mod_sys_fail(rb_mWaitWritable, "connect(2) would block");
- rsock_sys_fail_sockaddr("connect(2)", addr);
+ rsock_sys_fail_addrinfo_or_sockaddr("connect(2)", addr, rai);
}
return INT2FIX(n);
@@ -516,12 +541,13 @@ sock_connect_nonblock(VALUE sock, VALUE addr)
static VALUE
sock_bind(VALUE sock, VALUE addr)
{
+ VALUE rai;
rb_io_t *fptr;
- SockAddrStringValue(addr);
+ SockAddrStringValueWithAddrinfo(addr, rai);
GetOpenFile(sock, fptr);
if (bind(fptr->fd, (struct sockaddr*)RSTRING_PTR(addr), RSTRING_LENINT(addr)) < 0)
- rsock_sys_fail_sockaddr("bind(2)", addr);
+ rsock_sys_fail_addrinfo_or_sockaddr("bind(2)", addr, rai);
return INT2FIX(0);
}