[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
## question about mgetgroups()

**From**: |
Denis Excoffier |

**Subject**: |
question about mgetgroups() |

**Date**: |
Mon, 26 May 2014 22:00:49 +0200 |

Hello,
In mgetgroups.c, you can read the following piece of code:
--------------------------------------------------
if (username)
{
enum { N_GROUPS_INIT = 10 };
max_n_groups = N_GROUPS_INIT;
g = realloc_groupbuf (NULL, max_n_groups);
if (g == NULL)
return -1;
while (1)
{
gid_t *h;
int last_n_groups = max_n_groups;
/* getgrouplist updates max_n_groups to num required. */
ng = getgrouplist (username, gid, g, &max_n_groups);
/* Some systems (like Darwin) have a bug where they
never increase max_n_groups. */
if (ng < 0 && last_n_groups == max_n_groups)
max_n_groups *= 2;
if ((h = realloc_groupbuf (g, max_n_groups)) == NULL)
{
int saved_errno = errno;
free (g);
errno = saved_errno;
return -1;
}
g = h;
if (0 <= ng)
{
*groups = g;
/* On success some systems just return 0 from getgrouplist,
so return max_n_groups rather than ng. */
return max_n_groups;
}
}
}
--------------------------------------------------
Is it really necessary to realloc g when ng >= 0? The answer
could possibly be "Yes, in order to match with the exact number
of groups found", in particular in the Darwin case, where for
exemple 79 groups could remain unused when 81 are needed (here,
N_GROUPS_INIT=10).
Please observe however that (except in the Darwin case) the
realloc at the second (and last) iteration does not change the
allocated size. Therefore, the realloc() + "g = h" assignment
could possibly be surrounded by
if (last_n_groups != max_n_groups)
{
...
}
or even by
if (ng < 0 && last_n_groups != max_n_groups)
{
...
}
if the answer to the first question is, in fact, "No".
Or am i missing something? This has some (rather small) impact in coreutils/id.
Best regards,
Denis Excoffier.

**question about mgetgroups()**,
*Denis Excoffier* **<=**