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

НАИМЕНОВАНИЕ

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

БИБЛИОТЕКА

       Стандартная библиотека языка C (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(), 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("Usage: %s port-num proto-name [buflen]\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("Exceeded buffer limit (%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("Exceeded buffer limit (%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("Call failed/record not found\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> и Kirill Rekhov <krekhov.dev@gmail.com>

       Этот перевод является свободной программной документацией; он распространяется на условиях  общедоступной
       лицензии  GNU  (GNU  General Public License - GPL, https://www.gnu.org/licenses/gpl-3.0.html версии 3 или
       более поздней) в отношении авторского права, но БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ.

       Если вы обнаружите какие-либо ошибки в переводе этой страницы руководства, пожалуйста, сообщите  об  этом
       разработчику(ам)   по   его(их)  адресу(ам)  электронной  почты  или  по  адресу  списка рассылки русских
       переводчиков.

Справочные страницы Linux 6.9.1                  15 июня 2024 г.                                 getservent_r(3)