mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-08 17:42:12 +03:00
Remove 'grp' and merge into 'nss' and 'posix'
The majority of grp routines are entry points for nss functionality. This commit removes the 'grp' subdirectory and moves all nss-relevant functionality and all tests to 'nss', and the 'setgroups' stub into 'posix' (alongside the 'getgroups' stub). References to grp/ are accordingly changed. In addition, compat-initgroups.c, a fallback implementation of initgroups is renamed to initgroups-fallback.c so that the build system does not confuse it for nss_compat/compat-initgroups.c. Build time improves very slightly; e.g. down from an average of 45.5s to 44.5s on an 8-thread mobile x86_64 CPU. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
This commit is contained in:
116
nss/initgroups-fallback.c
Normal file
116
nss/initgroups-fallback.c
Normal file
@@ -0,0 +1,116 @@
|
||||
/* Prototype for the setgrent functions we use here. */
|
||||
typedef enum nss_status (*set_function) (void);
|
||||
|
||||
/* Prototype for the endgrent functions we use here. */
|
||||
typedef enum nss_status (*end_function) (void);
|
||||
|
||||
/* Prototype for the setgrent functions we use here. */
|
||||
typedef enum nss_status (*get_function) (struct group *, char *,
|
||||
size_t, int *);
|
||||
|
||||
|
||||
static enum nss_status
|
||||
compat_call (nss_action_list nip, const char *user, gid_t group, long int *start,
|
||||
long int *size, gid_t **groupsp, long int limit, int *errnop)
|
||||
{
|
||||
struct group grpbuf;
|
||||
enum nss_status status;
|
||||
set_function setgrent_fct;
|
||||
get_function getgrent_fct;
|
||||
end_function endgrent_fct;
|
||||
gid_t *groups = *groupsp;
|
||||
|
||||
getgrent_fct = __nss_lookup_function (nip, "getgrent_r");
|
||||
if (getgrent_fct == NULL)
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
|
||||
setgrent_fct = __nss_lookup_function (nip, "setgrent");
|
||||
if (setgrent_fct)
|
||||
{
|
||||
status = DL_CALL_FCT (setgrent_fct, ());
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
return status;
|
||||
}
|
||||
|
||||
endgrent_fct = __nss_lookup_function (nip, "endgrent");
|
||||
|
||||
struct scratch_buffer tmpbuf;
|
||||
scratch_buffer_init (&tmpbuf);
|
||||
enum nss_status result = NSS_STATUS_SUCCESS;
|
||||
|
||||
do
|
||||
{
|
||||
while ((status = DL_CALL_FCT (getgrent_fct,
|
||||
(&grpbuf, tmpbuf.data, tmpbuf.length,
|
||||
errnop)),
|
||||
status == NSS_STATUS_TRYAGAIN)
|
||||
&& *errnop == ERANGE)
|
||||
{
|
||||
if (!scratch_buffer_grow (&tmpbuf))
|
||||
{
|
||||
result = NSS_STATUS_TRYAGAIN;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (status != NSS_STATUS_SUCCESS)
|
||||
goto done;
|
||||
|
||||
if (grpbuf.gr_gid != group)
|
||||
{
|
||||
char **m;
|
||||
|
||||
for (m = grpbuf.gr_mem; *m != NULL; ++m)
|
||||
if (strcmp (*m, user) == 0)
|
||||
{
|
||||
/* Check whether the group is already on the list. */
|
||||
long int cnt;
|
||||
for (cnt = 0; cnt < *start; ++cnt)
|
||||
if (groups[cnt] == grpbuf.gr_gid)
|
||||
break;
|
||||
|
||||
if (cnt == *start)
|
||||
{
|
||||
/* Matches user and not yet on the list. Insert
|
||||
this group. */
|
||||
if (__glibc_unlikely (*start == *size))
|
||||
{
|
||||
/* Need a bigger buffer. */
|
||||
gid_t *newgroups;
|
||||
long int newsize;
|
||||
|
||||
if (limit > 0 && *size == limit)
|
||||
/* We reached the maximum. */
|
||||
goto done;
|
||||
|
||||
if (limit <= 0)
|
||||
newsize = 2 * *size;
|
||||
else
|
||||
newsize = MIN (limit, 2 * *size);
|
||||
|
||||
newgroups = realloc (groups,
|
||||
newsize * sizeof (*groups));
|
||||
if (newgroups == NULL)
|
||||
goto done;
|
||||
*groupsp = groups = newgroups;
|
||||
*size = newsize;
|
||||
}
|
||||
|
||||
groups[*start] = grpbuf.gr_gid;
|
||||
*start += 1;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (status == NSS_STATUS_SUCCESS);
|
||||
|
||||
done:
|
||||
scratch_buffer_free (&tmpbuf);
|
||||
|
||||
if (endgrent_fct)
|
||||
DL_CALL_FCT (endgrent_fct, ());
|
||||
|
||||
return result;
|
||||
}
|
Reference in New Issue
Block a user