
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.21] |
![]() |
|
Страницы: (17) « Первая ... 9 10 [11] 12 13 ... 16 17 все ( Перейти к последнему сообщению ) |
![]() |
Сообщ.
#151
,
|
|
Коллеги, я дико извиняюсь, но реально... до следующей недели мы в глубоком кранче. Позже я обязательно тут появлюсь и всё-всё почитаю.
|
![]() |
Сообщ.
#152
,
|
|
Та не бери в голову. Тема непереносимости низкоуровневых исключений по-любому больная, и где-то её всё равно приходится обсуждать.
Добавлено P.S. Я тем не менее с удовольствием посмотрел бы на транслятор сигналов POSIX в C++EH хотя бы краем глаза. Мог бы и сам заняться, но у меня никсов под рукой нет. Летом вот была убунта недолго, я даже успел одну из своих утилей и одну из библиотек под неё портировать. Добавлено P.P.S. Хотя лучше этот ваш POSIX никогда не трогать. Вообще. Вот сравни просто одну-единственную функцию-перечислитель сетевых интерфейсов. Скрытый текст ![]() ![]() // Функция перебора активных сетевых интерфейсов. Принимает функциональный объект, который // вызывается для каждого интерфейса и с параметрами назначенного адреса и маски его подсети. // Объект может вернуть false, если дальнейший перебор не требуется, и true для продолжения. template <int = AF_INET> inline void enumInterfaces(std::function<bool(in_addr, in_addr)> fn); template <> inline void enumInterfaces<AF_INET>(std::function<bool(in_addr, in_addr)> fn) { #ifdef WINHOST ULONG reqSize = 0; // получить список адаптеров... а, нет, тут только их количество if (ULONG retCode = GetAdaptersInfo(NULL, &reqSize); retCode != ERROR_BUFFER_OVERFLOW) throw APIerror("GetAdaptersInfo() fails.", retCode); // во, количество получили std::vector<unsigned char> infoBuffer(reqSize); IP_ADAPTER_INFO &info = reinterpret_cast<IP_ADAPTER_INFO&>(infoBuffer.front()); // получить список адаптеров if (ULONG retCode = GetAdaptersInfo(&info, &reqSize); retCode != ERROR_SUCCESS) throw APIerror("GetAdaptersInfo() is failed.", retCode); // проходим по списку интерфейсов и зовём fn for (PIP_ADAPTER_INFO adapter = &info; adapter != NULL; adapter = adapter->Next) { in_addr curAddr, netMask; curAddr.S_ADDR = inet_addr(adapter->IpAddressList.IpAddress.String); // подсеть if (curAddr.S_ADDR == 0) continue; // отключён netMask.S_ADDR = inet_addr(adapter->IpAddressList.IpMask.String); // её маска if (!fn(curAddr, netMask)) break; } #else ifconf conf; // здесь будет массив описаний интерфейсов int fd = socket(AF_INET, SOCK_DGRAM, 0); // для работы с интерфейсами нужен сокет if (fd < 0) throw Sockets::socket_error("Enum: socket() fails", WSAGetLastError()); constexpr size_t value_size = sizeof(ifreq); std::vector<char> buf; // буфер под массив, размер пока неизвестен try { // определить этот размер do { // увеличить размер буфера в полтора раза (в единицах размера ifreq) buf.resize(value_size * (buf.size()/value_size * 3/2 + 1)); // запросить информацию conf.ifc_len = buf.size(); conf.ifc_buf =&buf.front(); if (ioctl(fd, SIOCGIFCONF, &conf) != 0) throw Sockets::socket_error("Enum: ioctl(SIOCGIFCONF) fails", WSAGetLastError()); // пока возвращённый размер совпадает с запрошенным, предполагаем, что буфер недостаточен } while (conf.ifc_len == buf.size()); // теперь массив гарантировано может быть получен полностью const ifreq *req = reinterpret_cast<ifreq*>(conf.ifc_req); // перебираем все интерфейсы for (int i = 0; i < conf.ifc_len; i += value_size, ++req) { std::string host(16, ' '); // для адресов IPv4 этого хватит ifreq curReq; in_addr curAddr, netMask; // получаем адрес интерфейса (sockaddr) std::copy_n(std::begin(req->ifr_name), std::min(std::string_view(req->ifr_name).length() + 1, host.size()), std::begin(curReq.ifr_name)); if (ioctl(fd, SIOCGIFADDR, &curReq) != 0) continue; // интерфейсы с ошибками не интересуют if (curReq.ifr_addr.sa_family != AF_INET) continue; // интересуют только AF_INET // получаем адрес хоста в виде имени // (единственный независимый от конкретизации sockaddr вариант) if (getnameinfo(&curReq.ifr_addr, sizeof curReq.ifr_addr, &host.front(), host.size(), 0, 0, NI_NUMERICHOST) != 0) throw Sockets::socket_error("getnameinfo() fails", WSAGetLastError()); // переводим адрес в in_addr curAddr.s_addr = inet_addr(host.c_str()); // получаем маску подсети интерфейса if (ioctl(fd, SIOCGIFNETMASK, &curReq) != 0) throw Sockets::socket_error("Enum: ioctl(SIOCGIFNETMASK) fails", WSAGetLastError()); netMask = ((sockaddr_in*)&curReq.ifr_netmask)->sin_addr; if (!fn(curAddr, netMask)) break; } } catch(...) { close(fd); throw; } close(fd); #endif } } // Sockets #endif Добавлено P.P.P.S. Кто в коде заметит махонький ай-яй-яй, тому плюсик в карму ![]() Это сообщение было перенесено сюда или объединено из темы ""обработка исключений" vs "обработка кодов возврата"" |
Сообщ.
#153
,
|
|
|
Цитата Qraizer @ P.P.P.S. Кто в коде заметит махонький ай-яй-яй, тому плюсик в карму Сильно внимательно не смотрел, но по-моему тут есть а-я-я-й: последняя закрывающая фигурная скобка и последний #endif лишние - ибо они ничего не закрывают. Это сообщение было перенесено сюда или объединено из темы ""обработка исключений" vs "обработка кодов возврата"" |
![]() |
Сообщ.
#154
,
|
|
Ну это не считается. При копировании зацепился страж включения – это же фрагмент заголовка, самый конец – и namespace.
Это сообщение было перенесено сюда или объединено из темы ""обработка исключений" vs "обработка кодов возврата"" |
Сообщ.
#155
,
|
|
|
Цитата Qraizer @ Ай-яй не увидел ![]() Но мне не понравился алгоритм выделения буфера под интерфейсы. Я бы написал согласно доке на ioctl так: ![]() ![]() // определить этот размер // запросить информацию conf.ifc_len = 0; conf.ifc_req = NULL; if (ioctl(fd, SIOCGIFCONF, &conf) != 0) throw Sockets::socket_error("Enum: ioctl(SIOCGIFCONF) fails", WSAGetLastError()); std::vector<char> buf(conf.ifc_len); conf.ifc_len = buf.size(); conf.ifc_buf = &buf.front(); if (ioctl(fd, SIOCGIFCONF, &conf) != 0) throw Sockets::socket_error("Enum: ioctl(SIOCGIFCONF) fails", WSAGetLastError()); // теперь массив гарантировано может быть получен полностью const ifreq* req = reinterpret_cast<ifreq*>(conf.ifc_req); Это сообщение было перенесено сюда или объединено из темы ""обработка исключений" vs "обработка кодов возврата"" |
![]() |
Сообщ.
#156
,
|
|
sharky72, я бы с удовольствием, было б примерно как в WinAPI, та вот только POSIX он такой POSIX... Ты пишешь по linux mans, а как быть с openmans? Вот описание:
Цитата И никаких намёков даже на возможность NULL, не говоря уже о получении минимального требуемого размера.SIOCGIFCONF Возвращает список адресов интерфейса (транспортный уровень). Для поддержки совместимости в данный момент возвращаются только адреса семейства AF_INET (IPv4). Пользователь передает в качестве аргумента вызова ioctl структуру ifconf. Она содержит в поле ifc_req указатель на массив структур ifreq, а в поле ifc_len - его длину. Ядро заполняет структуры ifreq всеми текущими адресами третьего уровня (L3), связанными с интерфейсом и являющимися активными: ifr_name содержит имя интерфейса (eth0:1 и т.п.), ifr_addr содержит адрес. Ядра устанавливают длину массива равной ifc_len. Если ifc_len равно начальной длине, то пользователь должен предположить, что буфер переполнен, и попробовать еще раз проделать то же самое с буфером большего размера, чтобы в него поместились все адреса. Если ошибок не было, то ioctl возвращает 0, в противном случае -1. Переполнение не является ошибкой. Я не первый раз пробую POSIX. И каждый раз всё больше и больше склоняюсь к мысли, что называть POSIX стандартом нельзя. Когда работаешь с мульёном несовместимых редакций, это не стандарт. Это сообщение было перенесено сюда или объединено из темы ""обработка исключений" vs "обработка кодов возврата"" |
Сообщ.
#157
,
|
|
|
Цитата Majestio @ Ну можно замутить отдельную тему для общего участия. Но я бы принял участие только при одном условии - использование Шаблонов проектирования банды четырех Вот в перехвате и получении диагностики ничего такого смастерить не получается. И не нужно придумывать что-то специально. А вот в выводе полученной диагностики - да. Само получилось, без натягивания совы на глобус. --- Объект получился с характерными признаками декоратора и наблюдателя одновременно. Реальная жизнь интереснее голых схем. Это сообщение было перенесено сюда или объединено из темы ""обработка исключений" vs "обработка кодов возврата"" |
Сообщ.
#158
,
|
|
|
Цитата Qraizer @ Мда... И эти люди еще хаят WinAPI Это сообщение было перенесено сюда или объединено из темы ""обработка исключений" vs "обработка кодов возврата"" |
Сообщ.
#159
,
|
|
|
Цитата ЫукпШ @ И не нужно придумывать что-то специально. ![]() По сути, если я не ошибаюсь, следующий Си-подобный костыль, который маскируется под С++, нужно было бы как-то оформить ... Цитата sharky72 @ if (ioctl(fd, SIOCGIFCONF, &conf) != 0) throw Sockets::socket_error("Enum: ioctl(SIOCGIFCONF) fails", WSAGetLastError()); Допустим вынести все ioctl вызовы в класс ClassIoctl, который будет выступать либо "адаптером", либо "фасадом"? Не? Для *никсов что-то типа (упрощённо): ![]() ![]() #include <sys/ioctl.h> #include <fcntl.h> #include <unistd.h> #include <stdexcept> class ClassIoctl { private: int fd; // Дескриптор файла public: ClassIoctl(const char* device) { fd = open(device, O_RDWR); if (fd < 0) { throw std::runtime_error("Не удалось открыть устройство"); } } ~ClassIoctl() { close(fd); } template<typename T> void executeIoctl(unsigned long request, T& arg) { if (ioctl(fd, request, &arg) < 0) { throw std::runtime_error("Ошибка выполнения ioctl"); } } }; Это сообщение было перенесено сюда или объединено из темы ""обработка исключений" vs "обработка кодов возврата"" |
![]() |
Сообщ.
#160
,
|
|
И не говори, sharky72.
Majestio, ну и нахрена мне сдалось городить огород вокруг ...э-э-э, стандартного (? серьёзно? оно теперь так называется?) API? В WinAPI любые последующие ревизии никогда не изменяют и тем более отменяют предыдущие без того, чтобы завести новые и объявить что-то там deprecated, и впоследствии, дав время на порт, начать возвращать на старое GetLastError(). Мне же одних только этих берклиевых сокетов по горло хватило. С их 100500 несовместимых между собой вариантов. Куда не ткни, куча ноутов и фичей для всякоразных "единых" POSIX-реализаций. Танунафик этот nix, пусть себе и дальше форкает свои ядра наздоровье. Это сообщение было перенесено сюда или объединено из темы ""обработка исключений" vs "обработка кодов возврата"" |
Сообщ.
#161
,
|
|
|
Цитата Qraizer @ Majestio, ну и нахрена мне сдалось городить огород вокруг ...э-э-э, стандартного (? серьёзно? оно теперь так называется?) API? В WinAPI любые последующие ревизии никогда не изменяют и тем более отменяют предыдущие без того, чтобы завести новые и объявить что-то там deprecated, и впоследствии, дав время на порт, начать возвращать на старое GetLastError(). Мне же одних только этих берклиевых сокетов по горло хватило. С их 100500 несовместимых между собой вариантов. Куда не ткни, куча ноутов и фичей для всякоразных "единых" POSIX-реализаций. Танунафик этот nix, пусть себе и дальше форкает свои ядра наздоровье. ![]() ![]() Это сообщение было перенесено сюда или объединено из темы ""обработка исключений" vs "обработка кодов возврата"" |
Сообщ.
#162
,
|
|
|
Цитата Qraizer @ И не говори, sharky72. Majestio, ну и нахрена мне сдалось городить огород вокруг ...э-э-э, стандартного (? серьёзно? оно теперь так называется?) API? В WinAPI любые последующие ревизии никогда не изменяют и тем более отменяют предыдущие без того, чтобы завести новые и объявить что-то там deprecated, и впоследствии, дав время на порт, начать возвращать на старое GetLastError(). Мне же одних только этих берклиевых сокетов по горло хватило. С их 100500 несовместимых между собой вариантов. Куда не ткни, куча ноутов и фичей для всякоразных "единых" POSIX-реализаций. Танунафик этот nix, пусть себе и дальше форкает свои ядра наздоровье. Сравниваешь разные контексты. POSIX про разные ОС (не разные версии одной, а именно разные ОС), WinAPI - про одну. Конкретно под linux или конкретно под FreeBSD, или конкретно под macOS ты сможешь найти более стабильные и удачные решения (наверное, или они забили и сделали только POSIX). И так же для ecos, QNX и пр. и пр. Можно сколько угодно ругать POSIX, как "стандарт", но лучшего пока нет. И я не знаю, нужен ли. Но winapi это просто API конкретной ОС, а не стандарт. Это сообщение было перенесено сюда или объединено из темы ""обработка исключений" vs "обработка кодов возврата"" |
![]() |
Сообщ.
#163
,
|
|
D_KEY, и от этого должно сразу стать легче, что ль? Я пишу под Windows, и у меня WinAPI. Я пишу под nix, и у меня зоопарк. Мне глубоко фиолетово, что это разные ОС, ибо Windы тоже разные, но есть стандарт. POSIX не стандарт, так что этот хвалёный опенсоурс пусть идёт лесом, платный саппорт мне его не окупит. А вот бесплатный проприетарный мне ничего не будет стоить. Чисто экономически стоимость владения проприетарной ОСью для разработчиков в разы выгоднее.
Это сообщение было перенесено сюда или объединено из темы ""обработка исключений" vs "обработка кодов возврата"" |
Сообщ.
#164
,
|
|
|
Цитата Qraizer @ Я пишу под nix, и у меня зоопарк. А ты выбери конкретный *nix и зоопарка не будет. Добавлено Цитата Qraizer @ ибо Windы тоже разные, но есть стандарт. Винды разные версии, но ОС одна. Цитата так что этот хвалёный опенсоурс пусть идёт лесом, платный саппорт мне его не окупит. А вот бесплатный проприетарный мне ничего не будет стоить. Чисто экономически стоимость владения проприетарной ОСью для разработчиков в разы выгоднее. Все в одну кучу у тебя что-то. Опенсорс, проприетарность и nix. Это все разные вещи. macOS тоже nix, например. Но это уже оффтопик. Добавлено P.S. Когда я писал на winapi - это был самый ужасный период моей жизни, как разраба ![]() Сорри за оффтоп Это сообщение было перенесено сюда или объединено из темы ""обработка исключений" vs "обработка кодов возврата"" |
![]() |
Сообщ.
#165
,
|
|
D_KEY, ну не прикидывайся, что не понимаешь разницы между "разные ОС" и "разные API".
Добавлено Цитата D_KEY @ Та вот думаю, где тему резануть и в Холивары хвост скинуть...Сорри за оффтоп Это сообщение было перенесено сюда или объединено из темы ""обработка исключений" vs "обработка кодов возврата"" |