2004-11-03 13:51:07 +00:00
|
|
|
.\" Copyright (c) 2003 Andries Brouwer (aeb@cwi.nl)
|
|
|
|
.\"
|
|
|
|
.\" This is free documentation; you can redistribute it and/or
|
|
|
|
.\" modify it under the terms of the GNU General Public License as
|
|
|
|
.\" published by the Free Software Foundation; either version 2 of
|
|
|
|
.\" the License, or (at your option) any later version.
|
|
|
|
.\"
|
|
|
|
.\" The GNU General Public License's references to "object code"
|
|
|
|
.\" and "executables" are to be interpreted as the output of any
|
|
|
|
.\" document formatting or typesetting system, including
|
|
|
|
.\" intermediate and printed output.
|
|
|
|
.\"
|
|
|
|
.\" This manual is distributed in the hope that it will be useful,
|
|
|
|
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
.\" GNU General Public License for more details.
|
|
|
|
.\"
|
|
|
|
.\" You should have received a copy of the GNU General Public
|
|
|
|
.\" License along with this manual; if not, write to the Free
|
|
|
|
.\" Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111,
|
|
|
|
.\" USA.
|
|
|
|
.\"
|
|
|
|
.TH GETGRENT 3 2003-11-15 "GNU" "Linux Programmer's Manual"
|
|
|
|
.SH NAME
|
|
|
|
getgrent_r, fgetgrent_r \- get group file entry reentrantly
|
|
|
|
.SH SYNOPSIS
|
|
|
|
.nf
|
|
|
|
.B "#define _GNU_SOURCE"
|
|
|
|
.br
|
|
|
|
.B #include <grp.h>
|
|
|
|
.sp
|
|
|
|
.BI "int getgrent_r(struct group *" gbuf ", char *" buf ,
|
|
|
|
.br
|
|
|
|
.BI " size_t " buflen ", struct group **" gbufp );
|
|
|
|
.sp
|
|
|
|
.BI "int fgetgrent_r(FILE *" fp ", struct group *" gbuf ", char *" buf ,
|
|
|
|
.br
|
|
|
|
.BI " size_t " buflen ", struct group **" gbufp );
|
|
|
|
.SH DESCRIPTION
|
|
|
|
The functions
|
2005-10-19 07:07:02 +00:00
|
|
|
.BR getgrent_r ()
|
2004-11-03 13:51:07 +00:00
|
|
|
and
|
2005-10-19 07:07:02 +00:00
|
|
|
.BR fgetgrent_r ()
|
2004-11-03 13:51:07 +00:00
|
|
|
are the reentrant versions of
|
|
|
|
.BR getgrent (3)
|
|
|
|
and
|
|
|
|
.BR fgetgrent (3).
|
|
|
|
The former reads the next group entry from the stream initialized by
|
|
|
|
.BR setgrent (3).
|
|
|
|
The latter reads the next group entry from the stream
|
|
|
|
.I fp
|
|
|
|
given as parameter.
|
|
|
|
.PP
|
|
|
|
The \fIgroup\fP structure is defined in
|
|
|
|
.I <grp.h>
|
|
|
|
as follows:
|
|
|
|
.sp
|
|
|
|
.RS
|
|
|
|
.nf
|
|
|
|
struct group {
|
|
|
|
char *gr_name; /* group name */
|
|
|
|
char *gr_passwd; /* group password */
|
2005-07-19 06:20:42 +00:00
|
|
|
gid_t gr_gid; /* group ID */
|
2004-11-03 13:51:07 +00:00
|
|
|
char **gr_mem; /* group members */
|
|
|
|
};
|
|
|
|
.ta
|
|
|
|
.fi
|
|
|
|
.RE
|
|
|
|
.sp
|
|
|
|
The non-reentrant functions return a pointer to static storage,
|
|
|
|
where this static storage contains further pointers to group
|
|
|
|
name, password and members.
|
|
|
|
The reentrant functions described here return all of that in
|
|
|
|
caller-provided buffers. First of all there is the buffer
|
|
|
|
.I gbuf
|
|
|
|
that can hold a struct group. And next the buffer
|
|
|
|
.I buf
|
|
|
|
of size
|
|
|
|
.I buflen
|
|
|
|
that can hold additional strings.
|
|
|
|
The result of these functions, the struct group read from the stream,
|
|
|
|
is stored in the provided buffer
|
|
|
|
.RI * gbuf ,
|
|
|
|
and a pointer to this struct group is returned in
|
|
|
|
.RI * gbufp .
|
|
|
|
.SH "RETURN VALUE"
|
|
|
|
On success, these functions return 0 and
|
|
|
|
.RI * gbufp
|
|
|
|
is a pointer to the struct group.
|
|
|
|
On error, these functions return an error value and
|
|
|
|
.RI * gbufp
|
|
|
|
is NULL.
|
|
|
|
.SH ERRORS
|
|
|
|
.TP
|
|
|
|
.B ENOENT
|
|
|
|
No more entries.
|
|
|
|
.TP
|
|
|
|
.B ERANGE
|
|
|
|
Insufficient buffer space supplied. Try again with larger buffer.
|
|
|
|
.SH EXAMPLE
|
|
|
|
.nf
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
#include <grp.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#define BUFLEN 4096
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
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("\en");
|
|
|
|
}
|
|
|
|
endgrent();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
.fi
|
|
|
|
.\" perhaps add error checking - should use strerror_r
|
|
|
|
.\" #include <errno.h>
|
|
|
|
.\" #include <stdlib.h>
|
|
|
|
.\" if (i) {
|
|
|
|
.\" if (i == ENOENT)
|
|
|
|
.\" break;
|
|
|
|
.\" printf("getgrent_r: %s", strerror(i));
|
|
|
|
.\" exit(1);
|
|
|
|
.\" }
|
|
|
|
.SH "CONFORMING TO"
|
|
|
|
These functions are GNU extensions, done in a style resembling
|
|
|
|
the POSIX version of functions like
|
|
|
|
.BR getpwnam_r (3).
|
|
|
|
Other systems use prototype
|
|
|
|
.sp
|
|
|
|
.nf
|
|
|
|
.in +4
|
|
|
|
struct group *
|
|
|
|
getgrent_r(struct group *grp, char *buf, int buflen);
|
|
|
|
.in
|
|
|
|
.fi
|
|
|
|
.sp
|
|
|
|
or, better,
|
|
|
|
.sp
|
|
|
|
.nf
|
|
|
|
.in +4
|
|
|
|
int
|
|
|
|
getgrent_r(struct group *grp, char *buf, int buflen,
|
|
|
|
FILE **gr_fp);
|
|
|
|
.in
|
|
|
|
.fi
|
|
|
|
.sp
|
|
|
|
.SH NOTES
|
|
|
|
The function
|
2005-10-19 07:07:02 +00:00
|
|
|
.BR getgrent_r ()
|
2004-11-03 13:51:07 +00:00
|
|
|
is not really reentrant since it shares the reading position
|
|
|
|
in the stream with all other threads.
|
|
|
|
.SH "SEE ALSO"
|
|
|
|
.BR fgetgrent (3),
|
|
|
|
.BR getgrent (3),
|
|
|
|
.BR getgrgid (3),
|
|
|
|
.BR getgrnam (3),
|
2005-06-28 07:26:52 +00:00
|
|
|
.BR putgrent (3),
|
2004-11-03 13:51:07 +00:00
|
|
|
.BR group (5)
|