diff --git a/src/unix/aix.c b/src/unix/aix.c index 3af3009a..5aef7d1c 100644 --- a/src/unix/aix.c +++ b/src/unix/aix.c @@ -1120,6 +1120,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { struct ifreq *ifr, *p, flg; struct in6_ifreq if6; struct sockaddr_dl* sa_addr; + size_t namelen; + char* name; ifc.ifc_req = NULL; sock6fd = -1; @@ -1156,6 +1158,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { #define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p)) /* Count all up and running ipv4/ipv6 addresses */ + namelen = 0; ifr = ifc.ifc_req; while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) { p = ifr; @@ -1175,6 +1178,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING)) continue; + namelen += strlen(ent->ifa_name) + 1; (*count)++; } @@ -1182,8 +1186,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { goto cleanup; /* Alloc the return interface structs */ - *addresses = uv__calloc(*count, sizeof(**addresses)); - if (!(*addresses)) { + *addresses = uv__calloc(1, *count * sizeof(**addresses) + namelen); + if (*addresses == NULL) { r = UV_ENOMEM; goto cleanup; } @@ -1210,7 +1214,9 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { /* All conditions above must match count loop */ - address->name = uv__strdup(p->ifr_name); + namelen = strlen(p->ifr_name) + 1; + address->name = memcpy(name, p->ifr_name, namelen); + name += namelen; if (inet6) address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr); @@ -1282,13 +1288,7 @@ cleanup: void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; ++i) { - uv__free(addresses[i].name); - } - + int count) { uv__free(addresses); } diff --git a/src/unix/bsd-ifaddrs.c b/src/unix/bsd-ifaddrs.c index 11ca9559..8d9ebd25 100644 --- a/src/unix/bsd-ifaddrs.c +++ b/src/unix/bsd-ifaddrs.c @@ -65,13 +65,13 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) { return 0; } +/* TODO(bnoordhuis) share with linux.c */ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { + uv_interface_address_t* address; struct ifaddrs* addrs; struct ifaddrs* ent; - uv_interface_address_t* address; -#if !(defined(__CYGWIN__) || defined(__MSYS__)) && !defined(__GNU__) - int i; -#endif + size_t namelen; + char* name; *count = 0; *addresses = NULL; @@ -80,9 +80,11 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { return UV__ERR(errno); /* Count the number of interfaces */ + namelen = 0; for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR)) continue; + namelen += strlen(ent->ifa_name) + 1; (*count)++; } @@ -92,20 +94,22 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { } /* Make sure the memory is initiallized to zero using calloc() */ - *addresses = uv__calloc(*count, sizeof(**addresses)); - + *addresses = uv__calloc(1, *count * sizeof(**addresses) + namelen); if (*addresses == NULL) { freeifaddrs(addrs); return UV_ENOMEM; } + name = (char*) &(*addresses)[*count]; address = *addresses; for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR)) continue; - address->name = uv__strdup(ent->ifa_name); + namelen = strlen(ent->ifa_name) + 1; + address->name = memcpy(name, ent->ifa_name, namelen); + name += namelen; if (ent->ifa_addr->sa_family == AF_INET6) { address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); @@ -129,6 +133,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { #if !(defined(__CYGWIN__) || defined(__MSYS__)) && !defined(__GNU__) /* Fill in physical addresses for each interface */ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { + int i; + if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFPHYS)) continue; @@ -151,13 +157,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { } +/* TODO(bnoordhuis) share with linux.c */ void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(addresses[i].name); - } - uv__free(addresses); } diff --git a/src/unix/ibmi.c b/src/unix/ibmi.c index 837bba6e..fccce8b4 100644 --- a/src/unix/ibmi.c +++ b/src/unix/ibmi.c @@ -403,6 +403,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { return UV_ENOSYS; /* The first loop to get the size of the array to be allocated */ + namelen = 0; for (cur = ifap; cur; cur = cur->ifa_next) { if (!(cur->ifa_addr->sa_family == AF_INET6 || cur->ifa_addr->sa_family == AF_INET)) @@ -411,6 +412,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { if (!(cur->ifa_flags & IFF_UP && cur->ifa_flags & IFF_RUNNING)) continue; + namelen += strlen(cur->ifa_name) + 1; (*count)++; } @@ -420,11 +422,13 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { } /* Alloc the return interface structs */ - *addresses = uv__calloc(*count, sizeof(**addresses)); + *addresses = uv__calloc(1, *count * sizeof(**addresses) + namelen); if (*addresses == NULL) { Qp2freeifaddrs(ifap); return UV_ENOMEM; } + + name = (char*) &(*addresses)[*count]; address = *addresses; /* The second loop to fill in the array */ @@ -436,7 +440,9 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { if (!(cur->ifa_flags & IFF_UP && cur->ifa_flags & IFF_RUNNING)) continue; - address->name = uv__strdup(cur->ifa_name); + namelen = strlen(cur->ifa_name) + 1; + address->name = memcpy(name, cur->ifa_name, namelen); + name += namelen; inet6 = (cur->ifa_addr->sa_family == AF_INET6); @@ -497,13 +503,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { } -void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) { - int i; - - for (i = 0; i < count; ++i) { - uv__free(addresses[i].name); - } - +void uv_free_interface_addresses(uv_interface_address_t* addresses, + int count) { uv__free(addresses); } diff --git a/src/unix/linux.c b/src/unix/linux.c index 763f5dd5..86c12b4f 100644 --- a/src/unix/linux.c +++ b/src/unix/linux.c @@ -1954,11 +1954,15 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) { return !exclude_type; } +/* TODO(bnoordhuis) share with bsd-ifaddrs.c */ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { - struct ifaddrs *addrs, *ent; uv_interface_address_t* address; + struct sockaddr_ll* sll; + struct ifaddrs* addrs; + struct ifaddrs* ent; + size_t namelen; + char* name; int i; - struct sockaddr_ll *sll; *count = 0; *addresses = NULL; @@ -1967,10 +1971,12 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { return UV__ERR(errno); /* Count the number of interfaces */ + namelen = 0; for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR)) continue; + namelen += strlen(ent->ifa_name) + 1; (*count)++; } @@ -1980,19 +1986,22 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { } /* Make sure the memory is initiallized to zero using calloc() */ - *addresses = uv__calloc(*count, sizeof(**addresses)); - if (!(*addresses)) { + *addresses = uv__calloc(1, *count * sizeof(**addresses) + namelen); + if (*addresses == NULL) { freeifaddrs(addrs); return UV_ENOMEM; } + name = (char*) &(*addresses)[*count]; address = *addresses; for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR)) continue; - address->name = uv__strdup(ent->ifa_name); + namelen = strlen(ent->ifa_name) + 1; + address->name = memcpy(name, ent->ifa_name, namelen); + name += namelen; if (ent->ifa_addr->sa_family == AF_INET6) { address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); @@ -2036,14 +2045,9 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { } +/* TODO(bnoordhuis) share with bsd-ifaddrs.c */ void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(addresses[i].name); - } - + int count) { uv__free(addresses); } diff --git a/src/unix/sunos.c b/src/unix/sunos.c index 2d6bae79..84ce52a2 100644 --- a/src/unix/sunos.c +++ b/src/unix/sunos.c @@ -826,6 +826,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { uv_interface_address_t* address; struct ifaddrs* addrs; struct ifaddrs* ent; + size_t namelen; + char* name; *count = 0; *addresses = NULL; @@ -834,9 +836,11 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { return UV__ERR(errno); /* Count the number of interfaces */ + namelen = 0; for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (uv__ifaddr_exclude(ent)) continue; + namelen += strlen(ent->ifa_name) + 1; (*count)++; } @@ -845,19 +849,22 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { return 0; } - *addresses = uv__malloc(*count * sizeof(**addresses)); - if (!(*addresses)) { + *addresses = uv__calloc(1, *count * sizeof(**addresses) + namelen); + if (*addresses == NULL) { freeifaddrs(addrs); return UV_ENOMEM; } + name = (char*) &(*addresses)[*count]; address = *addresses; for (ent = addrs; ent != NULL; ent = ent->ifa_next) { if (uv__ifaddr_exclude(ent)) continue; - address->name = uv__strdup(ent->ifa_name); + namelen = strlen(ent->ifa_name) + 1; + address->name = memcpy(name, ent->ifa_name, namelen); + name += namelen; if (ent->ifa_addr->sa_family == AF_INET6) { address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); @@ -885,13 +892,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { #endif /* SUNOS_NO_IFADDRS */ void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(addresses[i].name); - } - + int count) { uv__free(addresses); }