gethostbyname - h_errno,
gethostbyname(3)
h_errno,
ОБЗОР
#include <netdb.h>
extern int h_errno;
struct hostent *gethostbyname(const char *name);
#include <sys/socket.h> /* для AF_INET */
struct hostent *gethostbyaddr(const void *addr,
socklen_t len, int type);
void sethostent(int stayopen);
void endhostent(void);
void herror(const char *s);
const char *hstrerror(int err);
/* расширение System V/POSIX */
struct hostent *gethostent(void);
/* расширения GNU */
struct hostent *gethostbyname2(const char *name, int af);
int gethostent_r(
struct hostent *ret, char *buf, size_t buflen,
struct hostent **result, int *h_errnop);
int gethostbyaddr_r(const void *addr, socklen_t len, int type,
struct hostent *ret, char *buf, size_t buflen,
struct hostent **result, int *h_errnop);
int gethostbyname_r(const char *name,
struct hostent *ret, char *buf, size_t buflen,
struct hostent **result, int *h_errnop);
int gethostbyname2_r(const char *name, int af,
struct hostent *ret, char *buf, size_t buflen,
struct hostent **result, int *h_errnop);
Требования макроса тестирования свойств для glibc
(см. feature_test_macros(7)):
gethostbyname2(), gethostent_r(), gethostbyaddr_r(),
gethostbyname_r(), gethostbyname2_r():
_BSD_SOURCE || _SVID_SOURCE
herror(), hstrerror():
Начиная с glibc 2.8:
_BSD_SOURCE || _SVID_SOURCE
До glibc 2.8:
ни одного
h_errno:
Начиная с glibc 2.12:
_BSD_SOURCE || _SVID_SOURCE ||
(_POSIX_C_SOURCE < 200809L && _XOPEN_SOURCE < 700)
До glibc 2.12:
ни одного
ОПИСАНИЕ
Функции
gethostbyname*(),
gethostbyaddr*(),
herror() и
hstrerror() являются устаревшими. Вместо них в приложениях следует
использовать
getaddrinfo(3),
getnameinfo(3) и
gai_strerror(3).
Функция gethostbyname() возвращает структуру типа hostent для узла
name. Значением name может быть или имя узла, или адрес IPv4 в
стандартной точечной записи (как в inet_addr(3)). Если name — адрес
IPv4, то поиск не выполняется и gethostbyname() просто копирует name в
поле h_name, а его эквивалент struct in_addr — в поле
h_addr_list[0] возвращаемой структуры hostent Если name не
оканчивается точкой и установлена переменная окружения HOSTALIASES, то
name сначала ищется в файле псевдонимов, указанном в HOSTALIASES
(формат файла описан в hostname(7)). Если name не оканчивается точкой,
то поиск производится с текущем доменом и его предками.
Функция gethostbyaddr() возвращает структуру типа hostent для адреса
узла addr длинной len и типом адреса type. Допустимые типы адресов
— AF_INET и AF_INET6. Аргумент адреса узла — указатель на структуру с
типом, зависящим от типа адреса, например для типа адреса AF_INET
используется struct in_addr * (возможно, полученная из вызова
inet_addr(3)).
Функция sethostent() задаёт (при stayopen равным истине (1)), что для
опроса сервера имён должен использоваться подключённый сокет TCP и что
соединение должно остаться открытым для последующих запросов. В противном
случае для опроса сервера имён будут использоваться дейтаграммы UDP.
Функция endhostent() закрывает использованное для опросов сервера имён
соединение TCP.
Функция herror() (устарела) печатает в stderr сообщение об ошибке в
соответствии с текущим значением h_errno.
Функция hstrerror() (устарела) принимает номер ошибки (обычно,
h_errno) и возвращает соответствующую строку с сообщением об ошибке.
Запросы доменного имени, выполняемые gethostbyname() и
gethostbyaddr(), полагаются на настроенные источники диспетчера службы
имён (nsswitch.conf(5)) или локальный сервер имён
(named(8)). Действием по умолчанию является запрос к настроенным
источникам диспетчера службы имён (nsswitch.conf(5)), при ошибке — к
локальному серверу имён (named(8)).
Историческая справка
Современным способом управления порядком поиска узлов является файл
nsswitch.conf(5).
В glibc 2.4 и старее, ключевое слово order использовалось для управления
порядком поиска узла в /etc/host.conf (host.conf(5)).
Структура hostent определена в <netdb.h> таким образом:
struct hostent {
char *h_name; /* официальное имя узла */
char **h_aliases; /* список псевдонимов */
int h_addrtype; /* тип адреса узла */
int h_length; /* длина адреса */
char **h_addr_list; /* список адресов */
}
#define h_addr h_addr_list[0] /* для обратной совместимости */
Члены структуры hostent:
h_name
Официальное имя узла.
h_aliases
Массив альтернативных имён узла, заканчивается указателем null.
h_addrtype
Тип адреса;
AF_INET или
AF_INET6.
h_length
Длина адреса в байтах.
h_addr_list
Массив указателей сетевых адресов узла (в сетевом порядке байт),
заканчивается указателем null.
h_addr
Первый адрес из
h_addr_list, для обратной совместимости.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
Функции
gethostbyname() и
gethostbyaddr() возвращают структуру
hostent или указатель null при ошибке. При ошибке переменная
h_errno
содержит номер ошибки. Если получен не NULL, то возвращаемое значение может
указывать на статические данные, смотрите замечание далее.
ОШИБКИ
Переменная
h_errno может содержать следующие значения:
HOST_NOT_FOUND
Заданный узел неизвестен.
NO_DATA
Запрашиваемое имя корректно, но не имеет IP-адреса. При другом типе запроса
для этого домена сервер имён может вернуть ответ. Синонимом NO_DATA
является константа NO_ADDRESS.
NO_RECOVERY
Произошла неисправимая ошибка сервера имён.
TRY_AGAIN
Произошла временная ошибка у авторитативного сервера имён. Попробуйте позже.
ФАЙЛЫ
/etc/host.conf
файл с настройками резолвера
/etc/hosts
файл базы данных узлов
/etc/nsswitch.conf
настройки диспетчера службы имён
АТРИБУТЫ
Описание терминов данного раздела смотрите в
attributes(7).
Интерфейс Атрибут Значение
gethostbyname()
безвредность в потоках:
MT-Unsafe race:hostbyname env
locale
gethostbyaddr()
безвредность в потоках:
MT-Unsafe race:hostbyaddr env
locale
sethostent(),
endhostent(),
gethostent_r()
безвредность в потоках:
MT-Unsafe race:hostent env
locale
herror(),
hstrerror()
безвредность в потоках: безвредно (MT-Safe)
gethostent()
безвредность в потоках:
MT-Unsafe race:hostent
race:hostentbuf env locale
gethostbyname2()
безвредность в потоках:
MT-Unsafe race:hostbyname2
env locale
gethostbyaddr_r(),
gethostbyname_r(),
gethostbyname2_r()
безвредность в потоках: безвредно (MT-Safe env locale)
В приведённой выше таблице hostent в race:hostent означает, что если в
нескольких нитях программы одновременно используются функции
sethostent(3), gethostent(3), gethostent_r(3) или endhostent(3),
то может возникнуть состязательность по данным.
СООТВЕТСТВИЕ СТАНДАРТАМ
В POSIX.1-2001 определены
gethostbyname(),
gethostbyaddr(),
sethostent(),
endhostent(),
gethostent() и
h_errno; функции
gethostbyname(),
gethostbyaddr() и
h_errno помечены как
устаревшие. В POSIX.1-2008 удалены определения
gethostbyname(),
gethostbyaddr() и
h_errno; вместо них рекомендуется использовать
getaddrinfo(3) и
getnameinfo(3).
ЗАМЕЧАНИЯ
Функции
gethostbyname() и
gethostbyaddr() могут возвращать указатели
на статические данные, которые могут быть перезаписаны при последующих
вызовах. Копирования
struct hostent недостаточно, так как она содержит
указатели; требуется глубокое копирование.
В первой реализации BSD аргумент len у gethostbyname() имел тип
int. Стандарт SUSv2 содержит ошибку и объявляет аргумент len у
gethostbyaddr() с типом size_t (это неправильно, так как он должен
быть int, а не size_t. В POSIX.1-2001 указанный тип — socklen_t,
который подходит). Смотрите также accept(2).
У прототипа BSD gethostbyaddr() первый аргумент имеет тип const char *.
Расширение System V/POSIX
В POSIX требуется вызов
gethostent(), который должен возвращать следующий
элемент из базы данных узлов. При использовании DNS/BIND это не имеет
смысла, но допустимо, если база данных узлов — файл, который можно читать
строку за строкой. На многих системах процедура с таким именем выполняет
чтение из файла
/etc/hosts. Она может быть доступна только когда
библиотека собрана без поддержки DNS. Версия glibc игнорирует записи
ipv6. Эта функция не реентерабельна; в glibc добавлена реентерабельная
версия
gethostent_r().
Расширения GNU
В glibc2 также имеется
gethostbyname2(), работающая подобно
gethostbyname(), но позволяющая задать адресное семейство, которому
должен принадлежать адрес.
В glibc2 также имеются реентерабельные версии gethostent_r(),
gethostbyaddr_r(), gethostbyname_r() и
gethostbyname2_r(). Вызывающий передаёт структуру hostent ret,
которая будет заполнена, и временный рабочий буфер buf размера
buflen. После вызова result будет указывать на результат. В случае
ошибки или при отсутствии записи result будет NULL. При успешном
выполнении функция возвращает 0 и ненулевой номер ошибки при сбое. Если
buf слишком мал, то кроме ошибок, возвращаемых нереентерабельными
версиями этих функций, возвращается ERANGE, и вызов нужно повторить с
большим буфером. Глобальная переменная h_errno не изменяется, но адрес
переменной, в которой хранятся номера ошибок, передаётся в h_errnop.
ДЕФЕКТЫ
Функция
gethostbyname() не работает с частями строки адреса IPv4 в
точечном формате, если они записаны шестнадцатеричными числами.