summaryrefslogtreecommitdiff
path: root/ext/socket/ifaddr.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/socket/ifaddr.c')
-rw-r--r--ext/socket/ifaddr.c59
1 files changed, 28 insertions, 31 deletions
diff --git a/ext/socket/ifaddr.c b/ext/socket/ifaddr.c
index 3c9548110e..3596c40a11 100644
--- a/ext/socket/ifaddr.c
+++ b/ext/socket/ifaddr.c
@@ -24,7 +24,6 @@ typedef struct rb_ifaddr_root_tag rb_ifaddr_root_t;
struct rb_ifaddr_tag {
int ord;
struct ifaddrs *ifaddr;
- rb_ifaddr_root_t *root;
};
struct rb_ifaddr_root_tag {
@@ -55,11 +54,12 @@ ifaddr_free(void *ptr)
static size_t
ifaddr_memsize(const void *ptr)
{
+ size_t size = offsetof(rb_ifaddr_root_t, ary);
const rb_ifaddr_t *ifaddr;
- const rb_ifaddr_root_t *root;
ifaddr = ptr;
- root = get_root(ifaddr);
- return sizeof(rb_ifaddr_root_t) + (root->numifaddrs - 1) * sizeof(rb_ifaddr_t);
+ if (ifaddr->ord == 0) size = sizeof(rb_ifaddr_root_t);
+ size += sizeof(struct ifaddrs);
+ return size;
}
static const rb_data_type_t ifaddr_type = {
@@ -84,6 +84,12 @@ get_ifaddr(VALUE self)
return rifaddr;
}
+static struct ifaddrs *
+get_ifaddrs(VALUE self)
+{
+ return get_ifaddr(self)->ifaddr;
+}
+
static VALUE
rsock_getifaddrs(void)
{
@@ -98,7 +104,7 @@ rsock_getifaddrs(void)
rb_sys_fail("getifaddrs");
if (!ifaddrs) {
- return rb_ary_new();
+ return rb_ary_new();
}
numifaddrs = 0;
@@ -106,7 +112,7 @@ rsock_getifaddrs(void)
numifaddrs++;
addr = TypedData_Wrap_Struct(rb_cSockIfaddr, &ifaddr_type, 0);
- root = xmalloc(sizeof(rb_ifaddr_root_t) + (numifaddrs-1) * sizeof(rb_ifaddr_t));
+ root = xmalloc(offsetof(rb_ifaddr_root_t, ary) + numifaddrs * sizeof(rb_ifaddr_t));
root->refcount = 0;
root->numifaddrs = numifaddrs;
@@ -114,7 +120,6 @@ rsock_getifaddrs(void)
for (i = 0; i < numifaddrs; i++) {
root->ary[i].ord = i;
root->ary[i].ifaddr = ifa;
- root->ary[i].root = root;
ifa = ifa->ifa_next;
}
RTYPEDDATA_DATA(addr) = &root->ary[0];
@@ -123,9 +128,9 @@ rsock_getifaddrs(void)
result = rb_ary_new2(numifaddrs);
rb_ary_push(result, addr);
for (i = 1; i < numifaddrs; i++) {
- addr = TypedData_Wrap_Struct(rb_cSockIfaddr, &ifaddr_type, &root->ary[i]);
- root->refcount++;
- rb_ary_push(result, addr);
+ addr = TypedData_Wrap_Struct(rb_cSockIfaddr, &ifaddr_type, &root->ary[i]);
+ root->refcount++;
+ rb_ary_push(result, addr);
}
return result;
@@ -141,8 +146,7 @@ rsock_getifaddrs(void)
static VALUE
ifaddr_name(VALUE self)
{
- rb_ifaddr_t *rifaddr = get_ifaddr(self);
- struct ifaddrs *ifa = rifaddr->ifaddr;
+ struct ifaddrs *ifa = get_ifaddrs(self);
return rb_str_new_cstr(ifa->ifa_name);
}
@@ -157,8 +161,7 @@ ifaddr_name(VALUE self)
static VALUE
ifaddr_ifindex(VALUE self)
{
- rb_ifaddr_t *rifaddr = get_ifaddr(self);
- struct ifaddrs *ifa = rifaddr->ifaddr;
+ struct ifaddrs *ifa = get_ifaddrs(self);
unsigned int ifindex = if_nametoindex(ifa->ifa_name);
if (ifindex == 0) {
rb_raise(rb_eArgError, "invalid interface name: %s", ifa->ifa_name);
@@ -174,13 +177,14 @@ ifaddr_ifindex(VALUE self)
* ifaddr.flags => integer
*
* Returns the flags of _ifaddr_.
+ *
+ * The value is bitwise-or of Socket::IFF_* constants such as Socket::IFF_LOOPBACK.
*/
static VALUE
ifaddr_flags(VALUE self)
{
- rb_ifaddr_t *rifaddr = get_ifaddr(self);
- struct ifaddrs *ifa = rifaddr->ifaddr;
+ struct ifaddrs *ifa = get_ifaddrs(self);
return IFAFLAGS2NUM(ifa->ifa_flags);
}
@@ -195,8 +199,7 @@ ifaddr_flags(VALUE self)
static VALUE
ifaddr_addr(VALUE self)
{
- rb_ifaddr_t *rifaddr = get_ifaddr(self);
- struct ifaddrs *ifa = rifaddr->ifaddr;
+ struct ifaddrs *ifa = get_ifaddrs(self);
if (ifa->ifa_addr)
return rsock_sockaddr_obj(ifa->ifa_addr, rsock_sockaddr_len(ifa->ifa_addr));
return Qnil;
@@ -213,8 +216,7 @@ ifaddr_addr(VALUE self)
static VALUE
ifaddr_netmask(VALUE self)
{
- rb_ifaddr_t *rifaddr = get_ifaddr(self);
- struct ifaddrs *ifa = rifaddr->ifaddr;
+ struct ifaddrs *ifa = get_ifaddrs(self);
if (ifa->ifa_netmask)
return rsock_sockaddr_obj(ifa->ifa_netmask, rsock_sockaddr_len(ifa->ifa_netmask));
return Qnil;
@@ -231,8 +233,7 @@ ifaddr_netmask(VALUE self)
static VALUE
ifaddr_broadaddr(VALUE self)
{
- rb_ifaddr_t *rifaddr = get_ifaddr(self);
- struct ifaddrs *ifa = rifaddr->ifaddr;
+ struct ifaddrs *ifa = get_ifaddrs(self);
if ((ifa->ifa_flags & IFF_BROADCAST) && ifa->ifa_broadaddr)
return rsock_sockaddr_obj(ifa->ifa_broadaddr, rsock_sockaddr_len(ifa->ifa_broadaddr));
return Qnil;
@@ -249,8 +250,7 @@ ifaddr_broadaddr(VALUE self)
static VALUE
ifaddr_dstaddr(VALUE self)
{
- rb_ifaddr_t *rifaddr = get_ifaddr(self);
- struct ifaddrs *ifa = rifaddr->ifaddr;
+ struct ifaddrs *ifa = get_ifaddrs(self);
if ((ifa->ifa_flags & IFF_POINTOPOINT) && ifa->ifa_dstaddr)
return rsock_sockaddr_obj(ifa->ifa_dstaddr, rsock_sockaddr_len(ifa->ifa_dstaddr));
return Qnil;
@@ -268,8 +268,7 @@ ifaddr_dstaddr(VALUE self)
static VALUE
ifaddr_vhid(VALUE self)
{
- rb_ifaddr_t *rifaddr = get_ifaddr(self);
- struct ifaddrs *ifa = rifaddr->ifaddr;
+ struct ifaddrs *ifa = get_ifaddrs(self);
if (ifa->ifa_data)
return (INT2FIX(((struct if_data*)ifa->ifa_data)->ifi_vhid));
else
@@ -359,12 +358,9 @@ ifaddr_inspect_flags(ifa_flags_t flags, VALUE result)
static VALUE
ifaddr_inspect(VALUE self)
{
- rb_ifaddr_t *rifaddr = get_ifaddr(self);
- struct ifaddrs *ifa;
+ struct ifaddrs *ifa = get_ifaddrs(self);
VALUE result;
- ifa = rifaddr->ifaddr;
-
result = rb_str_new_cstr("#<");
rb_str_append(result, rb_class_name(CLASS_OF(self)));
@@ -465,7 +461,8 @@ rsock_init_sockifaddr(void)
*
* Socket::Ifaddr represents a result of getifaddrs() function.
*/
- rb_cSockIfaddr = rb_define_class_under(rb_cSocket, "Ifaddr", rb_cData);
+ rb_cSockIfaddr = rb_define_class_under(rb_cSocket, "Ifaddr", rb_cObject);
+ rb_undef_alloc_func(rb_cSockIfaddr);
rb_define_method(rb_cSockIfaddr, "inspect", ifaddr_inspect, 0);
rb_define_method(rb_cSockIfaddr, "name", ifaddr_name, 0);
rb_define_method(rb_cSockIfaddr, "ifindex", ifaddr_ifindex, 0);