unix,win: make uv_interface_addresses() consistent

This commit does a few things to make the function more
consistent across platforms:

- Initialize the output parameters before everything else.
- Return early if there are no interfaces instead of performing
  zero-sized allocations.
- Add a missing memory deallocation.

Refs: https://github.com/libuv/libuv/pull/2035
PR-URL: https://github.com/libuv/libuv/pull/2039
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
This commit is contained in:
cjihrig 2018-10-15 09:24:35 -04:00
parent 69e4af1577
commit 5fb9517200
No known key found for this signature in database
GPG Key ID: 7434390BDBE9B9C5
6 changed files with 46 additions and 12 deletions

View File

@ -175,6 +175,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
struct sockaddr_dl* sa_addr;
*count = 0;
*addresses = NULL;
if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
return UV__ERR(errno);
@ -217,6 +218,11 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
(*count)++;
}
if (*count == 0) {
uv__close(sockfd);
return 0;
}
/* Alloc the return interface structs */
*addresses = uv__malloc(*count * sizeof(uv_interface_address_t));
if (!(*addresses)) {
@ -289,4 +295,4 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
}
uv__free(addresses);
}
}

View File

@ -69,11 +69,12 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
uv_interface_address_t* address;
int i;
*count = 0;
*addresses = NULL;
if (getifaddrs(&addrs) != 0)
return UV__ERR(errno);
*count = 0;
/* Count the number of interfaces */
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR))
@ -81,6 +82,11 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
(*count)++;
}
if (*count == 0) {
freeifaddrs(addrs);
return 0;
}
*addresses = uv__malloc(*count * sizeof(**addresses));
if (*addresses == NULL) {

View File

@ -829,6 +829,8 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) {
int uv_interface_addresses(uv_interface_address_t** addresses,
int* count) {
#ifndef HAVE_IFADDRS_H
*count = 0;
*addresses = NULL;
return UV_ENOSYS;
#else
struct ifaddrs *addrs, *ent;
@ -836,12 +838,12 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
int i;
struct sockaddr_ll *sll;
if (getifaddrs(&addrs))
return UV__ERR(errno);
*count = 0;
*addresses = NULL;
if (getifaddrs(&addrs))
return UV__ERR(errno);
/* Count the number of interfaces */
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR))
@ -850,8 +852,10 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
(*count)++;
}
if (*count == 0)
if (*count == 0) {
freeifaddrs(addrs);
return 0;
}
*addresses = uv__malloc(*count * sizeof(**addresses));
if (!(*addresses)) {

View File

@ -529,12 +529,14 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
struct ifreq* p;
int count_v6;
*count = 0;
*addresses = NULL;
/* get the ipv6 addresses first */
uv_interface_address_t* addresses_v6;
uv__interface_addresses_v6(&addresses_v6, &count_v6);
/* now get the ipv4 addresses */
*count = 0;
/* Assume maximum buffer size allowable */
maxsize = 16384;
@ -576,6 +578,11 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
(*count)++;
}
if (*count == 0) {
uv__close(sockfd);
return 0;
}
/* Alloc the return interface structs */
*addresses = uv__malloc((*count + count_v6) *
sizeof(uv_interface_address_t));
@ -750,7 +757,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
memcpy(reg_struct.__rfis_rftok, handle->rfis_rftok,
sizeof(handle->rfis_rftok));
/*
/*
* This call will take "/" as the path argument in case we
* don't care to supply the correct path. The system will simply
* ignore it.
@ -986,7 +993,7 @@ void uv__set_process_title(const char* title) {
}
int uv__io_fork(uv_loop_t* loop) {
/*
/*
Nullify the msg queue but don't close it because
it is still being used by the parent.
*/

View File

@ -692,6 +692,8 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
#ifdef SUNOS_NO_IFADDRS
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
*count = 0;
*addresses = NULL;
return UV_ENOSYS;
}
#else /* SUNOS_NO_IFADDRS */
@ -758,11 +760,12 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
struct ifaddrs* addrs;
struct ifaddrs* ent;
*count = 0;
*addresses = NULL;
if (getifaddrs(&addrs))
return UV__ERR(errno);
*count = 0;
/* Count the number of interfaces */
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (uv__ifaddr_exclude(ent))
@ -770,6 +773,11 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
(*count)++;
}
if (*count == 0) {
freeifaddrs(addrs);
return 0;
}
*addresses = uv__malloc(*count * sizeof(**addresses));
if (!(*addresses)) {
freeifaddrs(addrs);

View File

@ -816,6 +816,9 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
int is_vista_or_greater;
ULONG flags;
*addresses_ptr = NULL;
*count_ptr = 0;
is_vista_or_greater = is_windows_version_or_greater(6, 0, 0, 0);
if (is_vista_or_greater) {
flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST |