int getgrouplist(const char *user, gid_t group,
gid_t *groups, int *ngroups);
glibc 向けの機能検査マクロの要件 (feature_test_macros(7) 参照):
getgrouplist():
glibc 2.19 以降:
_DEFAULT_SOURCE
glibc 2.19 以前:
_BSD_SOURCE
引数 group がグループデータベースに user が所属するグループがなかった場合、 getgrouplist() が返すグループのリストに引数 group も追加される。 通常は、この引数にはユーザー user のパスワードレコードに書かれているグループ ID を指定する。
引数 ngroups は、値渡しと結果の両方に使用される引数 (value-result argument) であり、 リターン時には、常に group も含めた user が所属するグループ数が格納される。 この値は groups に格納されたグループ数より大きくなる可能性がある。
指定されたユーザーが *ngroups より多くのグループに所属している場合、 getgrouplist() は -1 を返す。 この場合、 *ngroups で返される値を使って、バッファーのサイズを変更してから、 getgrouplist() をもう一度呼び出すことができる。
インターフェース | 属性 | 値 |
getgrouplist() | Thread safety | MT-Safe locale |
$ ./a.out cecilia 0 getgrouplist() returned -1; ngroups = 3 $ ./a.out cecilia 3 ngroups = 3 16 (dialout) 33 (video) 100 (users)
int
main(int argc, char *argv[])
{
int ngroups;
struct passwd *pw;
struct group *gr;
if (argc != 3) {
fprintf(stderr, "Usage: %s <user> <ngroups>\n", argv[0]);
exit(EXIT_FAILURE);
}
ngroups = atoi(argv[2]);
gid_t *groups = malloc(sizeof(*groups) * ngroups);
if (groups == NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
/* Fetch passwd structure (contains first group ID for user) */
pw = getpwnam(argv[1]);
if (pw == NULL) {
perror("getpwnam");
exit(EXIT_SUCCESS);
}
/* Retrieve group list */
if (getgrouplist(argv[1], pw->pw_gid, groups, &ngroups) == -1) {
fprintf(stderr, "getgrouplist() returned -1; ngroups = %d\n",
ngroups);
exit(EXIT_FAILURE);
}
/* Display list of retrieved groups, along with group names */
fprintf(stderr, "ngroups = %d\n", ngroups);
for (int j = 0; j < ngroups; j++) {
printf("%d", groups[j]);
gr = getgrgid(groups[j]);
if (gr != NULL)
printf(" (%s)", gr->gr_name);
printf("\n");
}