Provided by: manpages-ru-dev_4.18.1-1_all bug

ИМЯ

       getservent_r,    getservbyname_r,   getservbyport_r   -   возвращает   запись   о   службе
       (реентерабельные версии)

LIBRARY

       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);

   Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

       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(),               │ Безвредность в нитях │ MT-Safe locale │
       │getservbyport_r()                                │                      │                │
       └─────────────────────────────────────────────────┴──────────────────────┴────────────────┘

СТАНДАРТЫ

       Эти функции являются расширениями  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
       <azamat.hackimov@gmail.com>,   Dmitry   Bolkhovskikh   <d20052005@yandex.ru>,    Vladislav
       <ivladislavefimov@gmail.com>,    Yuri    Kozlov   <yuray@komyakino.ru>   и   Иван   Павлов
       <pavia00@gmail.com>

       Этот  перевод  является  бесплатной  документацией;  прочитайте  Стандартную  общественную
       лицензию GNU версии 3 ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ или более позднюю, чтобы
       узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

       Если вы обнаружите ошибки в переводе  этой  страницы  руководства,  пожалуйста,  отправьте
       электронное письмо на ⟨man-pages-ru-talks@lists.sourceforge.net⟩.