1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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
This commit is contained in:
nobu 2015-05-16 12:57:17 +00:00
parent 6fb9349d85
commit b837025d77

View file

@ -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;