Browse Source

Yet more rework to make __getgrent and the functions that use it
reentrant...
-Erik

Eric Andersen 23 years ago
parent
commit
160212fe2d

+ 1 - 58
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;
 }

+ 4 - 51
libc/pwd_grp/config.h

@@ -27,9 +27,11 @@
 #include <grp.h>
 #include <shadow.h>
 
-/* 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 */

+ 22 - 5
libc/pwd_grp/fgetgrent.c

@@ -21,13 +21,30 @@
 #include <stdio.h>
 #include <errno.h>
 #include "config.h"
+    
+#ifdef __UCLIBC_HAS_THREADS__
+#include <pthread.h>
+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;
 }

+ 18 - 1
libc/pwd_grp/getgrgid.c

@@ -24,6 +24,20 @@
 #include <paths.h>
 #include "config.h"
 
+
+#ifdef __UCLIBC_HAS_THREADS__
+#include <pthread.h>
+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;
 }
 

+ 17 - 1
libc/pwd_grp/getgrnam.c

@@ -25,6 +25,19 @@
 #include <paths.h>
 #include "config.h"
 
+#ifdef __UCLIBC_HAS_THREADS__
+#include <pthread.h>
+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;
 }

+ 3 - 1
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;
 }

+ 27 - 25
libc/pwd_grp/initgroups.c

@@ -25,15 +25,24 @@
 #include <stdlib.h>
 #include "config.h"
 
+#ifdef __UCLIBC_HAS_THREADS__
+#include <pthread.h>
+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);
 }