getservent_r, getservbyname_r, getservbyport_r -
возвращает
запись о
службе
(реентерабельные
версии)
Standard C library (
libc,
-lc)
#include <netdb.h>
int getservent_r(struct servent *restrict result_buf,
char buf[restrict .buflen], size_t buflen,
struct servent **restrict result);
int getservbyname_r(const char *restrict name,
const char *restrict proto,
struct servent *restrict result_buf,
char buf[restrict .buflen], size_t buflen,
struct servent **restrict result);
int getservbyport_r(int port,
const char *restrict proto,
struct servent *restrict result_buf,
char buf[restrict .buflen], size_t buflen,
struct servent **restrict result);
getservent_r(),
getservbyname_r(),
getservbyport_r():
начиная с glibc 2.19:
_DEFAULT_SOURCE
в glibc 2.19 и старее:
_BSD_SOURCE || _SVID_SOURCE
Функции
getservent_r(),
getservbyname_r() и
getservbyport_r()
являются
реентерабельными
эквивалентами
getservent(3),
getservbyname(3) и
getservbyport(3),
соответственно.
Они
отличаются
способом
возврата
структуры
servent и
списком
параметров
и типом
возвращаемого
значения. В
этой
справочной
странице
описаны
только
различия с
нереентерабельными
функциями.
Вместо
возврата
указателя
на
статически
выделенную
структуру
servent в
качестве
результата
эти
функции
копируют
структуру
в
расположение,
указанное
result_buf.
Массив
buf
используется
для
хранения
строковых
полей из
возвращаемой
структуры
servent
(нереентерабельные
функции
выделяют
эти строки
из
статического
хранилища).
Размер
данного
массива
задаётся в
buflen. Если
buf
слишком
мал, то
вызов
завершается
с ошибкой
ERANGE,
вызывающий
должен его
повторить
с большим
буфером
(для
большинства
приложений
должно
быть
достаточно
буфера
длиной 1024
байт).
Если вызов
получил
запись о
службе, то
*result
указывает
на
result_buf; в
противном
случае
*result
устанавливается
в NULL.
При
успешном
выполнении
эти
функции
возвращают
0. При ошибке
возвращается
одно из
положительных
значений
ошибок.
При ошибке,
отсутствии
записи (
getservbyname_r(),
getservbyport_r()) или
конце
данных (
getservent_r())
значение
result
равно NULL.
- ENOENT
- (getservent_r())
Больше нет
записей в
базе
данных.
- ERANGE
- Размер buf
слишком
мал.
Попробуйте
ещё раз с
большим
буфером (и
увеличенным
значением
buflen).
Описание
терминов
данного
раздела
смотрите в
attributes(7).
Интерфейс |
Атрибут |
Значение |
getservent_r(), getservbyname_r(),
getservbyport_r() |
Безвредность
в нитях |
MT-Safe locale |
Эти
функции
являются
расширениями
GNU. Функции с
похожими
именами
есть и в
других
системах,
хотя и с
другим
набором
параметров.
Программа,
представленная
ниже,
использует
getservbyport_r() для
получения
записи о
службе для
заданного
порта и
протокола,
указанных
в
командной
строке.
Если задан
и третий
параметр
(целое), то он
используется
как
начальное
значение
buflen; если
getservbyport_r()
завершается
с ошибкой
ERANGE, то
программа
повторяет
попытки с
большими
значениями
буфера.
Пара
примеров
работы в
сеансовой
оболочке:
$ ./a.out 7 tcp 1
ERANGE! Повтор с большим буфером
getservbyport_r() returned: 0 (success) (buflen=87)
s_name=echo; s_proto=tcp; s_port=7; aliases=
$ ./a.out 77777 tcp
getservbyport_r() returned: 0 (success) (buflen=1024)
Ошибка вызова/запись не найдена
#define _GNU_SOURCE
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_BUF 10000
int
main(int argc, char *argv[])
{
int buflen, erange_cnt, port, s;
struct servent result_buf;
struct servent *result;
char buf[MAX_BUF];
char *protop;
if (argc < 3) {
printf("Использование: %s ном-порта имя-прото [длина-буф]\n", argv[0]);
exit(EXIT_FAILURE);
}
port = htons(atoi(argv[1]));
protop = (strcmp(argv[2], "null") == 0 ||
strcmp(argv[2], "NULL") == 0) ? NULL : argv[2];
buflen = 1024;
if (argc > 3)
buflen = atoi(argv[3]);
if (buflen > MAX_BUF) {
printf("Превышен размер буфера (%d)\n", MAX_BUF);
exit(EXIT_FAILURE);
}
erange_cnt = 0;
do {
s = getservbyport_r(port, protop, &result_buf,
buf, buflen, &result);
if (s == ERANGE) {
if (erange_cnt == 0)
printf("ERANGE! Retrying with larger buffer\n");
erange_cnt++;
/* Increment a byte at a time so we can see exactly
what size buffer was required. */
buflen++;
if (buflen > MAX_BUF) {
printf("Превышен размер буфера (%d)\n", MAX_BUF);
exit(EXIT_FAILURE);
}
}
} while (s == ERANGE);
printf("getservbyport_r() returned: %s (buflen=%d)\n",
(s == 0) ? "0 (success)" : (s == ENOENT) ? "ENOENT" :
strerror(s), buflen);
if (s != 0 || result == NULL) {
printf("Ошибка вызова/запись не найдена\n");
exit(EXIT_FAILURE);
}
printf("s_name=%s; s_proto=%s; s_port=%d; aliases=",
result_buf.s_name, result_buf.s_proto,
ntohs(result_buf.s_port));
for (char **p = result_buf.s_aliases; *p != NULL; p++)
printf("%s ", *p);
printf("\n");
exit(EXIT_SUCCESS);
}
getservent(3),
services(5)
Русский
перевод
этой
страницы
руководства
был сделан
Azamat Hackimov <
[email protected]>, Dmitry Bolkhovskikh
<
[email protected]>, Vladislav <
[email protected]>,
Yuri Kozlov <
[email protected]> и
Иван
Павлов <
[email protected]>
Этот
перевод
является
бесплатной
документацией;
прочитайте
Стандартную
общественную
лицензию GNU
версии 3
или более
позднюю,
чтобы
узнать об
условиях
авторского
права. Мы не
несем
НИКАКОЙ
ОТВЕТСТВЕННОСТИ.
Если вы
обнаружите
ошибки в
переводе
этой
страницы
руководства,
пожалуйста,
отправьте
электронное
письмо на
[email protected]