Other Alias
getprotoent_r, getprotobynumber_rОБЗОР
#include <netdb.h>
int getprotoent_r(struct protoent *result_buf, char *buf,
size_t buflen, struct protoent **result);
int getprotobyname_r(const char *name,
struct protoent *result_buf, char *buf,
size_t buflen, struct protoent **result);
int getprotobynumber_r(int proto,
struct protoent *result_buf, char *buf,
size_t buflen, struct protoent **result);
Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):
getprotoent_r(), getprotobyname_r(), getprotobynumber_r():
- _BSD_SOURCE || _SVID_SOURCE
ОПИСАНИЕ
Функции getprotoent_r(), getprotobyname_r() и getprotobynumber_r() являются реентерабельными эквивалентами getprotoent(3), getprotobyname(3) и getprotobynumber(3), соответственно. Они отличаются способом возврата структуры protoent, списком параметров и типом возвращаемого значения. В этой справочной странице описаны только различия с нереентерабельными функциями.Вместо возврата указателя на статически выделенную структуру protoent в качестве результата эти функции копируют структуру в расположение, указанное result_buf.
Массив buf используется для хранения строковых полей из возвращаемой структуры protoent (нереентерабельные функции выделяют эти строки из статического хранилища). Размер данного массива задаётся в buflen. Если buf слишком мал, то вызов завершается с ошибкой ERANGE, вызывающий должен его повторить с большим буфером (для большинства приложений должно быть достаточно буфера длиной 1024 байт).
Если вызов получил запись о протоколе, то *result указывает на result_buf; в противном случае *result устанавливается в NULL.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении эти функции возвращают 0. При ошибке возвращается одно из положительных значений, перечисленных В разделе ОШИБКИ.При ошибке, отсутствии записи (getprotobyname_r(), getprotobynumber_r()) или конце данных (getprotoent_r()) значение result равно NULL.
ОШИБКИ
- ENOENT
- (getprotoent_r()) Больше нет записей в базе данных.
- ERANGE
- Размер buf слишком мал. Попробуйте ещё раз с большим буфером (и увеличенным значением buflen).
АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).Интерфейс | Атрибут | Значение |
getprotoent_r(),
getprotobyname_r(), getprotobynumber_r() | безвредность в нитях | безвредно (MT-Safe locale) |
СООТВЕТСТВИЕ СТАНДАРТАМ
Эти функции являются расширениями GNU. Функции с похожими именами есть и в других системах, хотя и с другим набором параметров.ПРИМЕР
Программа, представленная ниже, использует getprotobyname_r() для получения записи о протоколе с именем, указанным в командной строке. Если задан второй параметр (целое), то он используется как начальное значение buflen; если getprotobyname_r() завершается с ошибкой ERANGE, то программа повторяет попытки с большими значениями буфера. Пара примеров работы в сеансовой оболочке:$ ./a.out tcp 1 ERANGE! Повтор с большим буфером результат getprotobyname_r(): 0 (успешно) (buflen=78) p_name=tcp; p_proto=6; aliases=TCP $ ./a.out xxx 1 ERANGE! Повтор с большим буфером результат getprotobyname_r(): 0 (успешно) (buflen=100) Ошибка вызова/запись не найдена
Исходный код программы
#define _GNU_SOURCE #include <ctype.h> #include <netdb.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #define MAX_BUF 10000 int main(int argc, char *argv[]) { int buflen, erange_cnt, s; struct protoent result_buf; struct protoent *result; char buf[MAX_BUF]; char **p; if (argc < 2) { printf("Использование: %s имя-протокола [длина-буф]\n", argv[0]); exit(EXIT_FAILURE); } buflen = 1024; if (argc > 2) buflen = atoi(argv[2]); if (buflen > MAX_BUF) { printf("Превышен размер буфера (%d)\n", MAX_BUF); exit(EXIT_FAILURE); } erange_cnt = 0; do { s = getprotobyname_r(argv[1], &result_buf, buf, buflen, &result); if (s == ERANGE) { if (erange_cnt == 0) printf("ERANGE! Повтор с большим буфером\n"); erange_cnt++; /* Увеличиваем по байту за раз для того, чтобы мы могли точно узнать какой размер буфера требуется */ buflen++; if (buflen > MAX_BUF) { printf("Превышен размер буфера (%d)\n", MAX_BUF); exit(EXIT_FAILURE); } } } while (s == ERANGE); printf("результат getprotobyname_r(): %s (buflen=%d)\n", (s == 0) ? "0 (успешно)" : (s == ENOENT) ? "ENOENT" : strerror(s), buflen); if (s != 0 || result == NULL) { printf("Ошибка вызова/запись не найдена\n"); exit(EXIT_FAILURE); } printf("p_name=%s; p_proto=%d; aliases=", result_buf.p_name, result_buf.p_proto); for (p = result_buf.p_aliases; *p != NULL; p++) printf("%s ", *p); printf("\n"); exit(EXIT_SUCCESS); }