Other Alias
getgrent_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(): _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); }