diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-05-16 12:57:17 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-05-16 12:57:17 +0000 |
commit | b837025d778f54ef132bca2b15a2dd769536ef2f (patch) | |
tree | d0b00cad1697fe288efea6fad9cad1f632561c50 /ext/socket/ifaddr.c | |
parent | 6fb9349d85960858023eb9c16826b68408279175 (diff) | |
download | ruby-b837025d778f54ef132bca2b15a2dd769536ef2f.tar.gz |
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.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/ext/socket/ifaddr.c b/ext/socket/ifaddr.c index 15395d7088..37edcaffb1 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; |