static int hadoop_group_info_fetch_reentrant(struct hadoop_group_info *ginfo, gid_t gid) { struct group *group; int err; size_t buf_sz; char *nbuf; for (;;) { do { group = NULL; err = getgrgid_r(gid, &ginfo->group, ginfo->buf, ginfo->buf_sz, &group); } while ((!group) && (err == EINTR)); if (group) { return 0; } if (err != ERANGE) { return getgrgid_error_translate(errno); } buf_sz = ginfo->buf_sz * 2; nbuf = realloc(ginfo->buf, buf_sz); if (!nbuf) { return ENOMEM; } ginfo->buf = nbuf; ginfo->buf_sz = buf_sz; } }
int hadoop_group_info_fetch(struct hadoop_group_info *ginfo, gid_t gid) { struct group *group; int ret; size_t buf_sz; char *nbuf; hadoop_group_info_clear(ginfo); for (;;) { // On success, the following call returns 0 and group is set to non-NULL. group = NULL; ret = getgrgid_r(gid, &ginfo->group, ginfo->buf, ginfo->buf_sz, &group); switch(ret) { case 0: if (!group) { // Not found. return ENOENT; } // Found. return 0; case EINTR: // EINTR: a signal was handled and this thread was allowed to continue. break; case ERANGE: // ERANGE: the buffer was not big enough. if (ginfo->buf_sz == MAX_GROUP_BUFFER_SIZE) { // Already tried with the max size. return ENOMEM; } buf_sz = ginfo->buf_sz * 2; if (buf_sz > MAX_GROUP_BUFFER_SIZE) { buf_sz = MAX_GROUP_BUFFER_SIZE; } nbuf = realloc(ginfo->buf, buf_sz); if (!nbuf) { return ENOMEM; } ginfo->buf = nbuf; ginfo->buf_sz = buf_sz; break; default: // Lookup failed. return getgrgid_error_translate(ret); } } }
static int hadoop_group_info_fetch_nonreentrant( struct hadoop_group_info *ginfo, gid_t gid) { struct group *group; int i, num_users = 0; char **g; do { errno = 0; group = getgrgid(gid); } while ((!group) && (errno == EINTR)); if (!group) { return getgrgid_error_translate(errno); } ginfo->group.gr_name = strdup(group->gr_name); if (!ginfo->group.gr_name) { hadoop_group_info_clear(ginfo); return ENOMEM; } ginfo->group.gr_passwd = strdup(group->gr_passwd); if (!ginfo->group.gr_passwd) { hadoop_group_info_clear(ginfo); return ENOMEM; } ginfo->group.gr_gid = group->gr_gid; if (group->gr_mem) { for (g = group->gr_mem, num_users = 0; *g; g++) { num_users++; } } ginfo->group.gr_mem = calloc(num_users + 1, sizeof(char *)); if (!ginfo->group.gr_mem) { hadoop_group_info_clear(ginfo); return ENOMEM; } for (i = 0; i < num_users; i++) { ginfo->group.gr_mem[i] = strdup(group->gr_mem[i]); if (!ginfo->group.gr_mem[i]) { hadoop_group_info_clear(ginfo); return ENOMEM; } } return 0; }