LINUX.ORG.RU

История изменений

Исправление 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 логике, лучше один раз их результаты (вернее их нужные части) сложить в вектор и спокойно обрабатывать далее.