summaryrefslogtreecommitdiff
path: root/ext/socket/ifaddr.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-05-16 12:57:17 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-05-16 12:57:17 +0000
commitb837025d778f54ef132bca2b15a2dd769536ef2f (patch)
treed0b00cad1697fe288efea6fad9cad1f632561c50 /ext/socket/ifaddr.c
parent6fb9349d85960858023eb9c16826b68408279175 (diff)
ifaddr.c: wrapper object before alloc
* ext/socket/ifaddr.c (rsock_getifaddrs): make wrapper object before result structs allocation and manage refcount for each elements to get rid of potential memory leak. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50512 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/socket/ifaddr.c')
-rw-r--r--ext/socket/ifaddr.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/ext/socket/ifaddr.c b/ext/socket/ifaddr.c
index 15395d7..37edcaf 100644
--- a/ext/socket/ifaddr.c
+++ b/ext/socket/ifaddr.c
@@ -98,7 +98,7 @@ rsock_getifaddrs(void)
int numifaddrs, i;
struct ifaddrs *ifaddrs, *ifa;
rb_ifaddr_root_t *root;
- VALUE result;
+ VALUE result, addr;
ret = getifaddrs(&ifaddrs);
if (ret == -1)
@@ -112,8 +112,10 @@ rsock_getifaddrs(void)
for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next)
numifaddrs++;
+ addr = TypedData_Wrap_Struct(rb_cSockIfaddr, &ifaddr_type, 0);
root = xmalloc(sizeof(rb_ifaddr_root_t) + (numifaddrs-1) * sizeof(rb_ifaddr_t));
- root->refcount = root->numifaddrs = numifaddrs;
+ root->refcount = 0;
+ root->numifaddrs = numifaddrs;
ifa = ifaddrs;
for (i = 0; i < numifaddrs; i++) {
@@ -122,10 +124,15 @@ rsock_getifaddrs(void)
root->ary[i].root = root;
ifa = ifa->ifa_next;
}
+ RTYPEDDATA_DATA(addr) = &root->ary[0];
+ root->refcount++;
result = rb_ary_new2(numifaddrs);
- for (i = 0; i < numifaddrs; i++) {
- rb_ary_push(result, TypedData_Wrap_Struct(rb_cSockIfaddr, &ifaddr_type, &root->ary[i]));
+ 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);
}
return result;