From 160212fe2d074af5bdc25b219e2276576f52b6e3 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Sun, 18 Aug 2002 18:50:52 +0000 Subject: Yet more rework to make __getgrent and the functions that use it reentrant... -Erik --- libc/pwd_grp/__getgrent.c | 59 +---------------------------------------------- libc/pwd_grp/config.h | 55 ++++--------------------------------------- libc/pwd_grp/fgetgrent.c | 27 ++++++++++++++++++---- libc/pwd_grp/getgrgid.c | 19 ++++++++++++++- libc/pwd_grp/getgrnam.c | 18 ++++++++++++++- libc/pwd_grp/grent.c | 4 +++- libc/pwd_grp/initgroups.c | 52 +++++++++++++++++++++-------------------- 7 files changed, 92 insertions(+), 142 deletions(-) (limited to 'libc') diff --git a/libc/pwd_grp/__getgrent.c b/libc/pwd_grp/__getgrent.c index e89f914ad..393c42de1 100644 --- a/libc/pwd_grp/__getgrent.c +++ b/libc/pwd_grp/__getgrent.c @@ -39,17 +39,10 @@ static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; * getgrent() except that it is passed a file descriptor. getgrent() * is just a wrapper for this function. */ -struct group *__getgrent(int grp_fd) +struct group *__getgrent(int grp_fd, char *line_buff, char **members) { -#ifdef GR_SCALE_DYNAMIC - static char *line_buff = NULL; - static char **members = NULL; short line_index; short buff_size; -#else - static char line_buff[GR_MAX_LINE_LEN]; - static char *members[GR_MAX_MEMBERS]; -#endif static struct group group; register char *ptr; char *field_begin; @@ -58,21 +51,15 @@ struct group *__getgrent(int grp_fd) int line_len; - LOCK; - /* We use the restart label to handle malformatted lines */ restart: -#ifdef GR_SCALE_DYNAMIC line_index = 0; buff_size = 256; -#endif -#ifdef GR_SCALE_DYNAMIC line_buff = realloc(line_buff, buff_size); while (1) { if ((line_len = read(grp_fd, line_buff + line_index, buff_size - line_index)) <= 0) { - UNLOCK; return NULL; } field_begin = strchr(line_buff, '\n'); @@ -92,33 +79,6 @@ restart: line_buff = realloc(line_buff, buff_size); } } -#else - /* Read the line into the static buffer */ - if ((line_len = read(grp_fd, line_buff, GR_MAX_LINE_LEN)) <= 0) { - UNLOCK; - return NULL; - } - field_begin = strchr(line_buff, '\n'); - if (field_begin != NULL) - lseek(grp_fd, (long) (1 + field_begin - (line_buff + line_len)), - SEEK_CUR); - else { /* The line is too long - skip it :-\ */ - - do { - if ((line_len = read(grp_fd, line_buff, GR_MAX_LINE_LEN)) <= 0) { - UNLOCK; - return NULL; - } - } while (!(field_begin = strchr(line_buff, '\n'))); - lseek(grp_fd, (long) ((field_begin - line_buff) - line_len + 1), - SEEK_CUR); - goto restart; - } - if (*line_buff == '#' || *line_buff == ' ' || *line_buff == '\n' || - *line_buff == '\t') - goto restart; - *field_begin = '\0'; -#endif /* GR_SCALE_DYNAMIC */ /* Now parse the line */ group.gr_name = line_buff; @@ -146,7 +106,6 @@ restart: member_num = 0; field_begin = ptr; -#ifdef GR_SCALE_DYNAMIC if (members != NULL) free(members); members = (char **) malloc((member_num + 1) * sizeof(char *)); @@ -159,22 +118,6 @@ restart: } members[member_num] = NULL; -#else - while ((ptr = strchr(ptr, ',')) != NULL) { - *ptr = '\0'; - ptr++; - members[member_num] = field_begin; - field_begin = ptr; - member_num++; - } - if (*field_begin == '\0') - members[member_num] = NULL; - else { - members[member_num] = field_begin; - members[member_num + 1] = NULL; - } -#endif group.gr_mem = members; - UNLOCK; return &group; } diff --git a/libc/pwd_grp/config.h b/libc/pwd_grp/config.h index 860f7dee9..25f450d6c 100644 --- a/libc/pwd_grp/config.h +++ b/libc/pwd_grp/config.h @@ -27,9 +27,11 @@ #include #include -/* These are used internally to uClibc */ -extern struct group * __getgrent __P ((int grp_fd)); +#define PWD_BUFFER_SIZE 256 + +/* These are used internally to uClibc */ +extern struct group *__getgrent(int grp_fd, char *line_buff, char **members); extern int __getpwent_r(struct passwd * passwd, char * line_buff, size_t buflen, int pwd_fd); extern int __getspent_r(struct spwd * spwd, char * line_buff, @@ -38,53 +40,4 @@ extern int __sgetspent_r(const char * string, struct spwd * spwd, char * line_buff, size_t buflen); -#define PWD_BUFFER_SIZE 256 - - -/* - * Define GR_SCALE_DYNAMIC if you want grp to dynamically scale its read buffer - * so that lines of any length can be used. On very very small systems, - * you may want to leave this undefined becasue it will make the grp functions - * somewhat larger (because of the inclusion of malloc and the code necessary). - * On larger systems, you will want to define this, because grp will _not_ - * deal with long lines gracefully (they will be skipped). - */ -/* - * Define GR_DYNAMIC_GROUP_LIST to make initgroups() dynamically allocate - * space for it's GID array before calling setgroups(). This is probably - * unnecessary scalage, so it's undefined by default. - */ -#ifdef __UCLIBC_HAS_MMU__ -#define GR_SCALE_DYNAMIC 1 -#define GR_DYNAMIC_GROUP_LIST 1 -#else -#undef GR_SCALE_DYNAMIC -#undef GR_DYNAMIC_GROUP_LIST -#endif - - - -#ifndef GR_SCALE_DYNAMIC -/* - * If scaling is not dynamic, the buffers will be statically allocated, and - * maximums must be chosen. GR_MAX_LINE_LEN is the maximum number of - * characters per line in the group file. GR_MAX_MEMBERS is the maximum - * number of members of any given group. - */ -#define GR_MAX_LINE_LEN 128 -/* GR_MAX_MEMBERS = (GR_MAX_LINE_LEN-(24+3+6))/9 */ -#define GR_MAX_MEMBERS 11 - -#endif /* !GR_SCALE_DYNAMIC */ - - -#ifndef GR_DYNAMIC_GROUP_LIST -/* - * GR_MAX_GROUPS is the size of the static array initgroups() uses for - * its static GID array if GR_DYNAMIC_GROUP_LIST isn't defined. - */ -#define GR_MAX_GROUPS 64 - -#endif /* !GR_DYNAMIC_GROUP_LIST */ - #endif /* !_CONFIG_GRP_H */ diff --git a/libc/pwd_grp/fgetgrent.c b/libc/pwd_grp/fgetgrent.c index 327802b86..b99df1c77 100644 --- a/libc/pwd_grp/fgetgrent.c +++ b/libc/pwd_grp/fgetgrent.c @@ -21,13 +21,30 @@ #include #include #include "config.h" + +#ifdef __UCLIBC_HAS_THREADS__ +#include +static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; +# define LOCK pthread_mutex_lock(&mylock) +# define UNLOCK pthread_mutex_unlock(&mylock); +#else +# define LOCK +# define UNLOCK +#endif +static char *line_buff = NULL; +static char **members = NULL; struct group *fgetgrent(FILE * file) { - if (file == NULL) { - __set_errno(EINTR); - return NULL; - } + struct group *grp; - return __getgrent(fileno(file)); + if (file == NULL) { + __set_errno(EINTR); + return NULL; + } + + LOCK; + grp = __getgrent(fileno(file), line_buff, members); + UNLOCK; + return grp; } diff --git a/libc/pwd_grp/getgrgid.c b/libc/pwd_grp/getgrgid.c index dc9176d39..5efca964a 100644 --- a/libc/pwd_grp/getgrgid.c +++ b/libc/pwd_grp/getgrgid.c @@ -24,6 +24,20 @@ #include #include "config.h" + +#ifdef __UCLIBC_HAS_THREADS__ +#include +static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; +# define LOCK pthread_mutex_lock(&mylock) +# define UNLOCK pthread_mutex_unlock(&mylock); +#else +# define LOCK +# define UNLOCK +#endif +static char *line_buff = NULL; +static char **members = NULL; + + struct group *getgrgid(const gid_t gid) { struct group *group; @@ -32,13 +46,16 @@ struct group *getgrgid(const gid_t gid) if ((grp_fd = open(_PATH_GROUP, O_RDONLY)) < 0) return NULL; - while ((group = __getgrent(grp_fd)) != NULL) + LOCK; + while ((group = __getgrent(grp_fd, line_buff, members)) != NULL) if (group->gr_gid == gid) { close(grp_fd); + UNLOCK; return group; } close(grp_fd); + UNLOCK; return NULL; } diff --git a/libc/pwd_grp/getgrnam.c b/libc/pwd_grp/getgrnam.c index f33462498..10302aab2 100644 --- a/libc/pwd_grp/getgrnam.c +++ b/libc/pwd_grp/getgrnam.c @@ -25,6 +25,19 @@ #include #include "config.h" +#ifdef __UCLIBC_HAS_THREADS__ +#include +static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; +# define LOCK pthread_mutex_lock(&mylock) +# define UNLOCK pthread_mutex_unlock(&mylock); +#else +# define LOCK +# define UNLOCK +#endif +static char *line_buff = NULL; +static char **members = NULL; + + struct group *getgrnam(const char *name) { int grp_fd; @@ -38,12 +51,15 @@ struct group *getgrnam(const char *name) if ((grp_fd = open(_PATH_GROUP, O_RDONLY)) < 0) return NULL; - while ((group = __getgrent(grp_fd)) != NULL) + LOCK; + while ((group = __getgrent(grp_fd, line_buff, members)) != NULL) if (!strcmp(group->gr_name, name)) { close(grp_fd); + UNLOCK; return group; } close(grp_fd); + UNLOCK; return NULL; } diff --git a/libc/pwd_grp/grent.c b/libc/pwd_grp/grent.c index 5ebcf265c..587fe0d93 100644 --- a/libc/pwd_grp/grent.c +++ b/libc/pwd_grp/grent.c @@ -41,6 +41,8 @@ static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; #endif static int grp_fd = -1; +static char *line_buff = NULL; +static char **members = NULL; void setgrent(void) { @@ -69,7 +71,7 @@ struct group *getgrent(void) UNLOCK; return NULL; } - r = __getgrent(grp_fd); + r = __getgrent(grp_fd, line_buff, members); UNLOCK; return r; } diff --git a/libc/pwd_grp/initgroups.c b/libc/pwd_grp/initgroups.c index fb19c0327..1596298e8 100644 --- a/libc/pwd_grp/initgroups.c +++ b/libc/pwd_grp/initgroups.c @@ -25,15 +25,24 @@ #include #include "config.h" +#ifdef __UCLIBC_HAS_THREADS__ +#include +static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER; +# define LOCK pthread_mutex_lock(&mylock) +# define UNLOCK pthread_mutex_unlock(&mylock); +#else +# define LOCK +# define UNLOCK +#endif + +static char *line_buff = NULL; +static char **members = NULL; + int initgroups(__const char *user, gid_t gid) { register struct group *group; -#ifndef GR_DYNAMIC_GROUP_LIST - gid_t group_list[GR_MAX_GROUPS]; -#else gid_t *group_list = NULL; -#endif register char **tmp_mem; int num_groups; int grp_fd; @@ -43,33 +52,26 @@ int initgroups(__const char *user, gid_t gid) return -1; num_groups = 0; -#ifdef GR_DYNAMIC_GROUP_LIST group_list = (gid_t *) realloc(group_list, 1); -#endif group_list[num_groups] = gid; -#ifndef GR_DYNAMIC_GROUP_LIST - while (num_groups < GR_MAX_GROUPS && - (group = __getgrent(grp_fd)) != NULL) -#else - while ((group = __getgrent(grp_fd)) != NULL) -#endif + LOCK; + while ((group = __getgrent(grp_fd, line_buff, members)) != NULL) + { + if (group->gr_gid != gid); { - if (group->gr_gid != gid); - { - tmp_mem = group->gr_mem; - while (*tmp_mem != NULL) { - if (!strcmp(*tmp_mem, user)) { - num_groups++; -#ifdef GR_DYNAMIC_GROUP_LIST - group_list = (gid_t *) realloc(group_list, num_groups * - sizeof(gid_t *)); -#endif - group_list[num_groups-1] = group->gr_gid; - } - tmp_mem++; + tmp_mem = group->gr_mem; + while (*tmp_mem != NULL) { + if (!strcmp(*tmp_mem, user)) { + num_groups++; + group_list = (gid_t *) realloc(group_list, num_groups * + sizeof(gid_t *)); + group_list[num_groups-1] = group->gr_gid; } + tmp_mem++; } } + } close(grp_fd); + UNLOCK; return setgroups(num_groups, group_list); } -- cgit v1.2.3