GETGRENT_R(3)

ИМЯ
getgrent_r, fgetgrent_r - возвращает запись из файла групп (реентерабельные версии)

ОБЗОР
#include <grp.h>

int getgrent_r(struct group *gbuf, char *buf,
               size_t buflen, struct group **gbufp);

int fgetgrent_r(FILE *stream, struct group *gbuf, char *buf,
                size_t buflen, struct group **gbufp);

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

getgrent_r(): _GNU_SOURCE
fgetgrent_r():
    начиная с glibc 2.19:
        _DEFAULT_SOURCE
    в glibc 2.19 и старее:
        _SVID_SOURCE

ОПИСАНИЕ
Функции getgrent_r() и fgetgrent_r() являются реентерабельными версиями getgrent(3) и fgetgrent(3). Первая читает следующую запись группы из потока, инициализированного setgrent(3). Последняя читает следующую запись группы из stream.

Структура group определена в <grp.h> следующим образом:

    struct group {
        char   *gr_name;        /* имя группы */
        char   *gr_passwd;      /* пароль группы */
        gid_t   gr_gid;         /* ID группы */
        char  **gr_mem;         /* массив, указателей
                                   имён членов группы, оканчивающийся NULL */
    };

Подробней о полях этой структуры смотрите в group(5).

Нереентерабельные версии возвращают указатель на статическое хранилище, в котором хранятся другие указатели на имя группы, пароль и список членов. Реентерабельные функции, описанные здесь, возвращают всю информацию в буферах, предоставленных вызывающим. Основным буфером является gbuf, в котором может храниться struct group. В дополнительном буфере buf размера buflen могут храниться дополнительные строки. Результат этих функций, прочитанная из потока struct group, сохраняется в предоставляемый буфер *gbuf, и указатель на эту struct group возвращается в *gbufp.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении эти функции возвращают 0 и *gbufp указывает на struct group. При ошибке возвращается значение ошибки и *gbufp равен NULL.

ОШИБКИ

ENOENT
    Больше записей нет.

ERANGE
    Недостаточно места в буфере. Попробуйте ещё раз с большим буфером.

АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).
Интерфейс | Атрибут | Значение
getgrent_r() | Безвредность в нитях | MT-Unsafe race:grent locale
fgetgrent_r() | Безвредность в нитях | MT-Safe

В приведённой выше таблице grent в race:grent означает, что если в нескольких нитях программы одновременно используются функции setgrent(), getgrent(), endgrent() или getgrent_r(), то может возникнуть состязательность по данным.

СООТВЕТСТВИЕ СТАНДАРТАМ
Эти функции являются расширениями GNU; они выполнены похожими на POSIX-версию функции getpwnam_r(3). В других системах используется прототип

    struct group *getgrent_r(struct group *grp, char *buf,
                             int buflen);

или, лучше,

    int getgrent_r(struct group *grp, char *buf, int buflen,
                   FILE **gr_fp);

ЗАМЕЧАНИЯ
Функция getgrent_r() не совсем реентерабельна, так как она использует общую позицию чтения в потоке с другими нитями.

ПРИМЕР
    #define _GNU_SOURCE
    #include <grp.h>
    #include <stdio.h>
    #include <stdlib.h>
    #define BUFLEN 4096
    int
    main(void)
    {
        struct group grp, *grpp;
        char buf[BUFLEN];
        int i;
        setgrent();
        while (1) {
            i = getgrent_r(&grp, buf, BUFLEN, &grpp);
            if (i)
                break;
            printf("%s (%d):", grpp->gr_name, grpp->gr_gid);
            for (i = 0; ; i++) {
                if (grpp->gr_mem[i] == NULL)
                    break;
                printf(" %s", grpp->gr_mem[i]);
            }
            printf("\n");
        }
        endgrent();
        exit(EXIT_SUCCESS);
    }

СМОТРИТЕ ТАКЖЕ
fgetgrent(3), getgrent(3), getgrgid(3), getgrnam(3), putgrent(3), group(5)