diff options
| -rw-r--r-- | src/passwd/fgetpwent.c | 4 | ||||
| -rw-r--r-- | src/passwd/getpw_a.c | 31 | ||||
| -rw-r--r-- | src/passwd/getpw_r.c | 36 | ||||
| -rw-r--r-- | src/passwd/getpwent.c | 32 | ||||
| -rw-r--r-- | src/passwd/getpwent_a.c | 8 | ||||
| -rw-r--r-- | src/passwd/pwf.h | 3 | 
6 files changed, 65 insertions, 49 deletions
| diff --git a/src/passwd/fgetpwent.c b/src/passwd/fgetpwent.c index eb47b2a1..fd472a07 100644 --- a/src/passwd/fgetpwent.c +++ b/src/passwd/fgetpwent.c @@ -6,5 +6,7 @@ struct passwd *fgetpwent(FILE *f)  	static char *line;  	static struct passwd pw;  	size_t size=0; -	return __getpwent_a(f, &pw, &line, &size); +	struct passwd *res; +	__getpwent_a(f, &pw, &line, &size, &res); +	return res;  } diff --git a/src/passwd/getpw_a.c b/src/passwd/getpw_a.c new file mode 100644 index 00000000..21efc5ca --- /dev/null +++ b/src/passwd/getpw_a.c @@ -0,0 +1,31 @@ +#include "pwf.h" +#include <pthread.h> + +int __getpw_a(const char *name, uid_t uid, struct passwd *pw, char **buf, size_t *size, struct passwd **res) +{ +	FILE *f; +	int cs; +	int rv = 0; + +	*res = 0; + +	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); + +	f = fopen("/etc/passwd", "rbe"); +	if (!f) { +		rv = errno; +		goto done; +	} + +	while (!(rv = __getpwent_a(f, pw, buf, size, res)) && *res) { +		if (name && !strcmp(name, (*res)->pw_name) +		|| !name && (*res)->pw_uid == uid) +			break; +	} +	fclose(f); + +done: +	pthread_setcancelstate(cs, 0); +	if (rv) errno = rv; +	return rv; +} diff --git a/src/passwd/getpw_r.c b/src/passwd/getpw_r.c index 28552572..0e71e43f 100644 --- a/src/passwd/getpw_r.c +++ b/src/passwd/getpw_r.c @@ -5,7 +5,6 @@  static int getpw_r(const char *name, uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)  { -	FILE *f;  	char *line = 0;  	size_t len = 0;  	int rv = 0; @@ -13,33 +12,20 @@ static int getpw_r(const char *name, uid_t uid, struct passwd *pw, char *buf, si  	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); -	f = fopen("/etc/passwd", "rbe"); -	if (!f) { -		rv = errno; -		goto done; +	rv = __getpw_a(name, uid, pw, &line, &len, res); +	if (!rv && size < len) { +		*res = 0; +		rv = ERANGE;  	} - -	*res = 0; -	while (__getpwent_a(f, pw, &line, &len)) { -		if (name && !strcmp(name, pw->pw_name) -		|| !name && pw->pw_uid == uid) { -			if (size < len) { -				rv = ERANGE; -				break; -			} -			*res = pw; -			memcpy(buf, line, len); -			FIX(name); -			FIX(passwd); -			FIX(gecos); -			FIX(dir); -			FIX(shell); -			break; -		} +	if (!rv) { +		memcpy(buf, line, len); +		FIX(name); +		FIX(passwd); +		FIX(gecos); +		FIX(dir); +		FIX(shell);  	}   	free(line); -	fclose(f); -done:  	pthread_setcancelstate(cs, 0);  	return rv;  } diff --git a/src/passwd/getpwent.c b/src/passwd/getpwent.c index c655135e..f2bd516e 100644 --- a/src/passwd/getpwent.c +++ b/src/passwd/getpwent.c @@ -1,6 +1,9 @@  #include "pwf.h"  static FILE *f; +static char *line; +static struct passwd pw; +static size_t size;  void setpwent()  { @@ -12,34 +15,23 @@ weak_alias(setpwent, endpwent);  struct passwd *getpwent()  { -	static char *line; -	static struct passwd pw; -	size_t size=0; +	struct passwd *res;  	if (!f) f = fopen("/etc/passwd", "rbe");  	if (!f) return 0; -	return __getpwent_a(f, &pw, &line, &size); +	__getpwent_a(f, &pw, &line, &size, &res); +	return res;  }  struct passwd *getpwuid(uid_t uid)  { -	struct passwd *pw; -	int errno_saved; -	setpwent(); -	while ((pw=getpwent()) && pw->pw_uid != uid); -	errno_saved = errno; -	endpwent(); -	errno = errno_saved; -	return pw; +	struct passwd *res; +	__getpw_a(0, uid, &pw, &line, &size, &res); +	return res;  }  struct passwd *getpwnam(const char *name)  { -	struct passwd *pw; -	int errno_saved; -	setpwent(); -	while ((pw=getpwent()) && strcmp(pw->pw_name, name)); -	errno_saved = errno; -	endpwent(); -	errno = errno_saved; -	return pw; +	struct passwd *res; +	__getpw_a(name, 0, &pw, &line, &size, &res); +	return res;  } diff --git a/src/passwd/getpwent_a.c b/src/passwd/getpwent_a.c index 34842a07..4d84f0d5 100644 --- a/src/passwd/getpwent_a.c +++ b/src/passwd/getpwent_a.c @@ -8,14 +8,16 @@ static unsigned atou(char **s)  	return x;  } -struct passwd *__getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size) +int __getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size, struct passwd **res)  {  	ssize_t l;  	char *s; +	int rv = 0;  	int cs;  	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);  	for (;;) {  		if ((l=getline(line, size, f)) < 0) { +			rv = errno;  			free(*line);  			*line = 0;  			pw = 0; @@ -46,5 +48,7 @@ struct passwd *__getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *siz  		break;  	}  	pthread_setcancelstate(cs, 0); -	return pw; +	*res = pw; +	if (rv) errno = rv; +	return rv;  } diff --git a/src/passwd/pwf.h b/src/passwd/pwf.h index 2d813ada..806ffd31 100644 --- a/src/passwd/pwf.h +++ b/src/passwd/pwf.h @@ -8,6 +8,7 @@  #include <limits.h>  #include "libc.h" -struct passwd *__getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size); +int __getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size, struct passwd **res); +int __getpw_a(const char *name, uid_t uid, struct passwd *pw, char **buf, size_t *size, struct passwd **res);  struct group *__getgrent_a(FILE *f, struct group *gr, char **line, size_t *size, char ***mem, size_t *nmem);  int __parsespent(char *s, struct spwd *sp); | 
