getgrent(3)

๐Ÿ’– getgrent(3) ๐Ÿ’–

omg bestie hi!! so this is literally the getgrent page from the Library Functions Manual (that's the 3 in getgrent(3) โ€” library functions, not syscalls, iykyk) and it's all about reading the group database. it's giving โœจgroup loreโœจ. let's get into it ๐Ÿซถ


๐ŸŒธ NAME ๐ŸŒธ

getgrent, setgrent, endgrent โ€” get group file entry ๐ŸŽ€

๐Ÿ“š LIBRARY ๐Ÿ“š

Standard C library (libc, -lc) โ€” yes queen, you gotta link the C library, that's the vibe ๐Ÿ’…

โœจ SYNOPSIS โœจ

okay so first you gotta pull in the headers, no cap:

#include <sys/types.h>
#include <grp.h>

then here's the trio of functions ๐Ÿฆ‹:

struct group *getgrent(void);

void setgrent(void);
void endgrent(void);

๐Ÿงš Feature Test Macro Requirements for glibc ๐Ÿงš

(go look at feature_test_macros(7) if you're lost, bestie โ€” it explains all this)

setgrent():

_XOPEN_SOURCE >= 500
    || /* glibc >= 2.19: */ _DEFAULT_SOURCE
    || /* glibc <= 2.19: */ _BSD_SOURCE || _SVID_SOURCE

getgrent(), endgrent():

Since glibc 2.22:
    _XOPEN_SOURCE >= 500 || _DEFAULT_SOURCE
glibc 2.21 and earlier
    _XOPEN_SOURCE >= 500
        || /* Since glibc 2.12: */ _POSIX_C_SOURCE >= 200809L
        || /* glibc <= 2.19: */ _BSD_SOURCE || _SVID_SOURCE

like, yes, the version matters, the #defines are NOT one-size-fits-all, periodt ๐Ÿ˜ค


๐Ÿ’œ DESCRIPTION ๐Ÿ’œ

okay so the main character here is getgrent(). it hands you back a pointer to a structure stuffed with the broken-out fields of a record from the group database โ€” and when we say "the group database" we mean stuff like the local group file /etc/group, plus NIS and LDAP, she's flexible ๐Ÿ’….

the first time you call getgrent(), you get the first entry. after that? successive entries, one at a time, like a little conveyor belt of groups ๐Ÿ“.

setgrent() is the rewind button โ€” it goes back to the very beginning of the group database so you can scan the whole thing again ๐Ÿ”.

endgrent() is the "we're done here, close the group database" function. clean up after yourself, bestie ๐Ÿงน.

the group structure lives in <grp.h> and looks exactly like this, don't @ me:

struct group {
    char   *gr_name;        /* group name */
    char   *gr_passwd;      /* group password */
    gid_t   gr_gid;         /* group ID */
    char  **gr_mem;         /* NULL-terminated array of pointers
                               to names of group members */
};

want the full tea on what each field means? go read group(5), it's all there ๐Ÿ’–


๐Ÿ‘‘ RETURN VALUE ๐Ÿ‘‘

getgrent() gives you a pointer to a group structure. or NULL โ€” either because there are no more entries, or because an error happened ๐Ÿ˜ญ (yes, same NULL, you gotta check errno to tell them apart, life is unfair).

on error, errno may be set. and if you actually wanna check errno after the call? set it to zero before the call. that's the move, no cap.

โš ๏ธ big heads up bestie: the return value may point to a static area, and it can get overwritten by later calls to getgrent(), getgrgid(3), or getgrnam(3). so don't go holding onto it like it's yours forever. and do NOT pass that returned pointer to free(3). literally do not. it is not yours to free ๐Ÿ’€

๐Ÿ’€ ERRORS ๐Ÿ’€

here's the whole roster of ways things can go sideways:

  • EAGAIN โ€” the service was temporarily unavailable; try again later. for NSS backends in glibc this means there was a temporary error talking to the backend. it might fix itself, so retrying later is suggested ๐Ÿซ 
  • EINTR โ€” a signal was caught; go see signal(7) โœ‹
  • EIO โ€” I/O error ๐Ÿ˜ต
  • EMFILE โ€” the per-process limit on the number of open file descriptors has been reached ๐Ÿšซ
  • ENFILE โ€” the system-wide limit on the total number of open files has been reached ๐ŸŒŠ
  • ENOENT โ€” a necessary input file cannot be found. for NSS backends in glibc this means the backend is not correctly configured ๐Ÿ”
  • ENOMEM โ€” insufficient memory to allocate group structure ๐Ÿ˜ญ
  • ERANGE โ€” insufficient buffer space supplied ๐Ÿ“

๐Ÿ“ FILES ๐Ÿ“

  • /etc/group โ€” the local group database file ๐Ÿ—‚๏ธ

๐Ÿ’… ATTRIBUTES ๐Ÿ’…

for what all these terms even mean, check attributes(7) โ€” it's the glossary, bestie.

(the original is a whole table, so here it is as a list, same facts, cuter packaging ๐ŸŽ€)

  • getgrent() โ€” Thread safety: <hotpink>MT-Unsafe race:grent race:grentbuf locale</hotpink>
  • setgrent(), endgrent() โ€” Thread safety: <hotpink>MT-Unsafe race:grent locale</hotpink>

and about that grent in race:grent: it means that if any of setgrent(), getgrent(), or endgrent() get used in parallel across different threads of your program, then data races could occur. so likeโ€ฆ threads + grent = chaos ๐ŸŒ€


๐ŸŒˆ STANDARDS ๐ŸŒˆ

POSIX.1-2008. we stan a standard ๐Ÿ‘‘


๐Ÿ“œ HISTORY ๐Ÿ“œ

POSIX.1-2001, SVr4, 4.3BSD โ€” she's been around a minute, an absolute icon ๐ŸŒŸ


๐Ÿ”ฅ SEE ALSO ๐Ÿ”ฅ

fgetgrent(3), getgrent_r(3), getgrgid(3), getgrnam(3), getgrouplist(3), putgrent(3), group(5)


and that's the whole page, bestie!! this one's from Linux man-pages 6.20, dated 2026-02-08 โ€” go forth and read your group database responsibly ๐Ÿ’–โœจ๐Ÿฆ‹

๐Ÿ“ฆ where this page comes from
  • arch rolling: man-pages 6.20-1 ยท BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
  • nixpkgs unstable: man-pages 6.20
  • ๐Ÿ“œ the page's license: Linux-man-pages-copyleft
  • ๐Ÿ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms