Browse Source

Fix things (properly) to open /etc/passd and /etc/group if
they have not yet been opened.

My last try was completely and embarrasingly broken.
-Erik

Eric Andersen 20 năm trước cách đây
mục cha
commit
fabd08e854
4 tập tin đã thay đổi với 36 bổ sung24 xóa
  1. 0 3
      libc/pwd_grp/__getgrent_r.c
  2. 0 3
      libc/pwd_grp/__getpwent_r.c
  3. 10 4
      libc/pwd_grp/grent.c
  4. 26 14
      libc/pwd_grp/pwent.c

+ 0 - 3
libc/pwd_grp/__getgrent_r.c

@@ -44,9 +44,6 @@ int __getgrent_r (struct group *__restrict group,
 		return ERANGE;
 	}
 
-	if (grp_fd==-1)
-		setgrent();
-
 	/* We use the restart label to handle malformatted lines */
 restart:
 	/* Read the group line into the buffer for processing */

+ 0 - 3
libc/pwd_grp/__getpwent_r.c

@@ -47,9 +47,6 @@ int __getpwent_r(struct passwd * passwd, char * line_buff, size_t buflen, int pw
 		return ERANGE;
 	}
 
-	if (pwd_fd == -1)
-		setpwent();
-
 	/* We use the restart label to handle malformatted lines */
 restart:
 	/* Read the passwd line into the buffer for processing */

+ 10 - 4
libc/pwd_grp/grent.c

@@ -26,6 +26,7 @@
  * in together.
  */
 
+#define _GNU_SOURCE
 #include <features.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -35,7 +36,7 @@
 
 #ifdef __UCLIBC_HAS_THREADS__
 #include <pthread.h>
-static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 # define LOCK   pthread_mutex_lock(&mylock)
 # define UNLOCK pthread_mutex_unlock(&mylock);
 #else       
@@ -43,12 +44,13 @@ static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
 # define UNLOCK
 #endif      
 
-static int grp_fd = -1;
+/* file descriptor for the group file currently open */
+static int grp_fd = -9;
 
 void setgrent(void)
 {
 	LOCK;
-	if (grp_fd != -1)
+	if (grp_fd > -1)
 		close(grp_fd);
 	grp_fd = open(_PATH_GROUP, O_RDONLY);
 	UNLOCK;
@@ -57,7 +59,7 @@ void setgrent(void)
 void endgrent(void)
 {
 	LOCK;
-	if (grp_fd != -1)
+	if (grp_fd > -1)
 		close(grp_fd);
 	grp_fd = -1;
 	UNLOCK;
@@ -70,6 +72,10 @@ struct group *getgrent(void)
 	static char line_buff[PWD_BUFFER_SIZE];
 
 	LOCK;
+	/* Open /etc/group if it has never been opened */
+	if (grp_fd == -9) {
+		setgrent();
+	}
 	if (grp_fd == -1) {
 		UNLOCK;
 		return NULL;

+ 26 - 14
libc/pwd_grp/pwent.c

@@ -20,6 +20,13 @@
  *
  */
 
+/*
+ * setpwent(), endpwent(), and getpwent() are included in the same object
+ * file, since one cannot be used without the other two, so it makes sense to
+ * link them all in together.
+ */
+
+#define _GNU_SOURCE
 #include <features.h>
 #include <unistd.h>
 #include <stdlib.h>
@@ -30,7 +37,7 @@
 
 #ifdef __UCLIBC_HAS_THREADS__
 #include <pthread.h>
-static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 # define LOCK   pthread_mutex_lock(&mylock)
 # define UNLOCK pthread_mutex_unlock(&mylock);
 #else       
@@ -38,21 +45,14 @@ static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
 # define UNLOCK
 #endif      
 
-/*
- * setpwent(), endpwent(), and getpwent() are included in the same object
- * file, since one cannot be used without the other two, so it makes sense to
- * link them all in together.
- */
-
 /* file descriptor for the password file currently open */
-static int pw_fd = -1;
+static int pw_fd = -9;
 
 void setpwent(void)
 {
 	LOCK;
-	if (pw_fd != -1)
+	if (pw_fd > -1)
 		close(pw_fd);
-
 	pw_fd = open(_PATH_PASSWD, O_RDONLY);
 	UNLOCK;
 }
@@ -60,7 +60,7 @@ void setpwent(void)
 void endpwent(void)
 {
 	LOCK;
-	if (pw_fd != -1)
+	if (pw_fd > -1)
 		close(pw_fd);
 	pw_fd = -1;
 	UNLOCK;
@@ -86,13 +86,25 @@ int getpwent_r (struct passwd *password, char *buff,
 struct passwd *getpwent(void)
 {
 	int ret;
-	static char line_buff[PWD_BUFFER_SIZE];
-	static struct passwd pwd;
 	struct passwd *result;
+	static struct passwd pwd;
+	static char line_buff[PWD_BUFFER_SIZE];
 
-	if ((ret=getpwent_r(&pwd, line_buff, sizeof(line_buff), &result)) == 0) {
+	LOCK;
+	/* Open /etc/passwd if not yet opened */
+	if (pw_fd == -9) {
+		setpwent();
+	}
+	if (pw_fd == -1) {
+		UNLOCK;
+		return NULL;
+	}
+	ret=getpwent_r(&pwd, line_buff, sizeof(line_buff), &result);
+	if (ret == 0) {
+		UNLOCK;
 		return &pwd;
 	}
+	UNLOCK;
 	__set_errno(ret);
 	return NULL;
 }