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 togetgrent(),getgrgid(3), orgetgrnam(3). so don't go holding onto it like it's yours forever. and do NOT pass that returned pointer tofree(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 seesignal(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
- Copyright 1993, David Metcalfe <david@prism.demon.co.uk>
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms