История изменений
Исправление Siborgium, (текущая версия) :
Когда я вижу такой код, мне всегда становится интересно, что было у пациента в голове, когда он его писал. Подозреваю впрочем, что было пусто – в сознание пациент не приходил.
Возьмем например getSockToIP
и пойдем по порядку, начиная с деталей. Почему в switch нет default на случай если в sa_family что-то иное? Зачем делать calloc
на данные, которые затем будут скопированы в строку? Что если assign выкинет исключение? Где проверка на ошибки inet_ntop?
Добавим теперь чуть контекста. getSockToIP
нужна только для getIPAddr
. Каждый раз там будет делаться calloc, потом такая же аллокация в std::string, затем будет переаллоцироваться общий буфер, в который будут копироваться данные. Вместе с этим, все длины известны заранее. Все известно заранее, тебе нужно выделить одну единственную строчку и записать в нее все твои данные.
constexpr size_t addrstrlen(sa_family_t family) {
switch (family) {
case AF_INET: return INET_ADDRSTRLEN;
case AF_INET6: return INET6_ADDRSTRLEN;
default: throw std::logic_error{"addrstrlen: unknown family"};
}
std::string get_ip_addr(const struct ifaddrs& pifa) {
char buf[max(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) * 2 + 2];
char* ptr = buf;
if (pifa.ifa_addr) {
*ptr++ = ' ';
const size_t len = addrstrlen(pifa.ifa_addr->sa_family);
if (!inet_ntop(pifa.ida_addr->sa_family, pifa.ifa_addr, ptr, len) {
throw /* exception with errno */;
}
ptr += len;
}
/* аналогично для ifa_netmask */
return { buf, ptr - buf };
}
и так далее.
Суть задачи проста - получить параметры одного или всех сетевых интерфейсов, понятно что можно в векторе, например, вернуть, но можно как то вот хитрожопо сделать через std::function или что то иное есть???
Суть задачи проста: сделать хитрожопо. Чем тебя не устроил вектор, зачем тебе std::function, что иное тебе нужно – неясно. Вместо того, чтобы постоянно гонять getifaddrs/freeifaddrs в exception-unsafe логике, лучше один раз их результаты (вернее их нужные части) сложить в вектор и спокойно обрабатывать далее.
Исправление Siborgium, :
Когда я вижу такой код, мне всегда становится интересно, что было у пациента в голове, когда он его писал. Подозреваю впрочем, что было пусто – в сознание пациент не приходил.
Возьмем например getSockToIP
и пойдем по порядку, начиная с деталей. Почему в switch нет default на случай если в sa_family что-то иное? Зачем делать calloc
на данные, которые затем будут скопированы в строку? Что если assign выкинет исключение? Где проверка на ошибки inet_ntop?
Добавим теперь чуть контекста. getSockToIP
нужна только для getIPAddr
. Каждый раз там будет делаться calloc, потом такая же аллокация в std::string, затем будет переаллоцироваться общий буфер, в который будут копироваться данные. Вместе с этим, все длины известны заранее. Все известно заранее, тебе нужно выделить одну единственную строчку и записать в нее все твои данные.
constexpr size_t addrstrlen(sa_family_t family) {
switch (family) {
case AF_INET: return INET_ADDRSTRLEN;
case AF_INET6: return INET6_ADDRSTRLEN;
default: throw std::logic_error{"addrstrlen: unknown family"};
}
std::string get_ip_addr(const struct ifaddrs& pifa) {
char buf[max(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) * 2 + 3]; // 2 spaces, 1 null-terminator
char* ptr = buf;
if (pifa.ifa_addr) {
*ptr++ = ' ';
const size_t len = addrstrlen(pifa.ifa_addr->sa_family);
if (!inet_ntop(pifa.ida_addr->sa_family, pifa.ifa_addr, ptr, len) {
throw /* exception with errno */;
}
ptr += len;
}
/* аналогично для ifa_netmask */
return { buf, ptr - buf };
}
и так далее.
Суть задачи проста - получить параметры одного или всех сетевых интерфейсов, понятно что можно в векторе, например, вернуть, но можно как то вот хитрожопо сделать через std::function или что то иное есть???
Суть задачи проста: сделать хитрожопо. Чем тебя не устроил вектор, зачем тебе std::function, что иное тебе нужно – неясно. Вместо того, чтобы постоянно гонять getifaddrs/freeifaddrs в exception-unsafe логике, лучше один раз их результаты (вернее их нужные части) сложить в вектор и спокойно обрабатывать далее.
Исправление Siborgium, :
Когда я вижу такой код, мне всегда становится интересно, что было у пациента в голове, когда он его писал. Подозреваю впрочем, что было пусто – в сознание пациент не приходил.
Возьмем например getSockToIP
и пойдем по порядку, начиная с деталей. Почему в switch нет default на случай если в sa_family что-то иное? Зачем делать calloc
на данные, которые затем будут скопированы в строку? Что если assign выкинет исключение? Где проверка на ошибки inet_ntop?
Добавим теперь чуть контекста. getSockToIP
нужна только для getIPAddr
. Каждый раз там будет делаться calloc, потом такая же аллокация в std::string, затем будет переаллоцироваться общий буфер, в который будут копироваться данные. Вместе с этим, все длины известны заранее. Все известно заранее, тебе нужно выделить одну единственную строчку и записать в нее все твои данные.
constexpr size_t addrstrlen(sa_family_t family) {
switch (family) {
case AF_INET: return INET_ADDRSTRLEN;
case AF_INET6: return INET6_ADDRSTRLEN;
default: throw std::logic_error{"addrstrlen: unknown family"};
}
std::string get_ip_addr(const struct ifaddrs& pifa) {
char buf[max(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) * 2 + 3]; // 2 spaces, 1 null-terminator
char* ptr = buf;
if (pifa.ifa_addr) {
*ptr++ = ' ';
const size_t len = addrstrlen(pifa.ifa_addr->sa_family);
if (!inet_ntop(pifa.ida_addr->sa_family, pifa.ifa_addr, ptr, len) {
throw /* exception with errno */;
}
ptr += len;
}
/* аналогично для ifa_netmask */
ptr = std::fill(ptr, std::end(buf), '\0');
return { buf, ptr - buf };
}
и так далее.
Суть задачи проста - получить параметры одного или всех сетевых интерфейсов, понятно что можно в векторе, например, вернуть, но можно как то вот хитрожопо сделать через std::function или что то иное есть???
Суть задачи проста: сделать хитрожопо. Чем тебя не устроил вектор, зачем тебе std::function, что иное тебе нужно – неясно. Вместо того, чтобы постоянно гонять getifaddrs/freeifaddrs в exception-unsafe логике, лучше один раз их результаты (вернее их нужные части) сложить в вектор и спокойно обрабатывать далее.
Исходная версия Siborgium, :
Когда я вижу такой код, мне всегда становится интересно, что было у пациента в голове, когда он его писал. Подозреваю впрочем, что было пусто – в сознание пациент не приходил.
Возьмем например getSockToIP
и пойдем по порядку, начиная с деталей. Почему в switch нет default на случай если в sa_family что-то иное? Зачем делать calloc
на данные, которые затем будут скопированы в строку? Что если assign выкинет исключение? Где проверка на ошибки inet_ntop?
Добавим теперь чуть контекста. getSockToIP
нужна только для getIPAddr
. Каждый раз там будет делаться calloc, потом такая же аллокация в std::string, затем будет переаллоцироваться общий буфер, в который будут копироваться данные. Вместе с этим, все длины известны заранее. Все известно заранее, тебе нужно выделить одну единственную строчку и записать в нее все твои данные.
constexpr size_t addrstrlen(sa_family_t family) {
switch (family) {
case AF_INET: return INET_ADDRSTRLEN;
case AF_INET6: return INET6_ADDRSTRLEN;
default: throw std::logic_error{"addrstrlen: unknown family"};
}
std::string get_ip_addr(const struct ifaddrs& pifa) {
char buf[max(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) * 2 + 3]; // 2 spaces, 1 null-terminator
char* ptr = buf;
if (pifa.ifa_addr) {
*ptr++ = ' ';
const size_t len = addrstrlen(pifa.ifa_addr->sa_family);
if (!inet_ntop(pifa.ida_addr->sa_family, pifa.ifa_addr, ptr, len) {
throw /* exception with errno */;
}
ptr += len;
}
/* аналогично для ifa_netmask */
std::fill(ptr, std::end(buf), '\0');
return { buf, sizeof(buf) };
}
и так далее.
Суть задачи проста - получить параметры одного или всех сетевых интерфейсов, понятно что можно в векторе, например, вернуть, но можно как то вот хитрожопо сделать через std::function или что то иное есть???
Суть задачи проста: сделать хитрожопо. Чем тебя не устроил вектор, зачем тебе std::function, что иное тебе нужно – неясно. Вместо того, чтобы постоянно гонять getifaddrs/freeifaddrs в exception-unsafe логике, лучше один раз их результаты (вернее их нужные части) сложить в вектор и спокойно обрабатывать далее.