dovecot-2.2: i_get(pw|gr)(nam|uid): Use small initial buffer sizes.

dovecot at dovecot.org dovecot at dovecot.org
Tue Sep 11 18:56:18 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/349d52c4ca51
changeset: 15039:349d52c4ca51
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Sep 11 18:56:07 2012 +0300
description:
i_get(pw|gr)(nam|uid): Use small initial buffer sizes.
For processes that need to do only a single lookup there's no point in
wasting a lot of memory for the maximum buffer size.

diffstat:

 src/lib/ipwd.c |  64 ++++++++++++++++++++++++++++++---------------------------
 1 files changed, 34 insertions(+), 30 deletions(-)

diffs (115 lines):

diff -r 92cc78c5dc77 -r 349d52c4ca51 src/lib/ipwd.c
--- a/src/lib/ipwd.c	Mon Sep 10 17:19:43 2012 +0300
+++ b/src/lib/ipwd.c	Tue Sep 11 18:56:07 2012 +0300
@@ -6,41 +6,33 @@
 
 #include <unistd.h>
 
-#define DEFAULT_PWBUF_SIZE 16384
-#define DEFAULT_GRBUF_SIZE 16384
+#define PWBUF_MIN_SIZE 128
+#define GRBUF_MIN_SIZE 128
 
 static void *pwbuf = NULL, *grbuf = NULL;
 static size_t pwbuf_size, grbuf_size;
 
 static void pw_init(void)
 {
-	long size;
+	size_t old_pwbuf_size = pwbuf_size;
 
-	if (pwbuf == NULL) {
-		size = sysconf(_SC_GETPW_R_SIZE_MAX);
-		if (size < 0)
-			size = DEFAULT_PWBUF_SIZE;
-
-		pwbuf_size = size;
-		pwbuf = i_malloc(pwbuf_size);
+	if (pwbuf == NULL || errno == ERANGE) {
+		pwbuf_size = nearest_power(old_pwbuf_size + 1);
+		if (pwbuf_size < PWBUF_MIN_SIZE)
+			pwbuf_size = PWBUF_MIN_SIZE;
+		pwbuf = i_realloc(pwbuf, old_pwbuf_size, pwbuf_size);
 	}
 }
 
 static void gr_init(void)
 {
-	long size;
+	size_t old_grbuf_size = grbuf_size;
 
-	if (grbuf == NULL) {
-		size = sysconf(_SC_GETGR_R_SIZE_MAX);
-		/* Some BSDs return too low value for this. instead of trying
-		   to figure out exactly which, just make sure it's at least
-		   a reasonable size. if the real size is smaller, it doesn't
-		   matter much that we waste a few kilobytes of memory. */
-		if (size < DEFAULT_GRBUF_SIZE)
-			size = DEFAULT_GRBUF_SIZE;
-
-		grbuf_size = size;
-		grbuf = i_malloc(grbuf_size);
+	if (grbuf == NULL || errno == ERANGE) {
+		grbuf_size = nearest_power(old_grbuf_size + 1);
+		if (grbuf_size < PWBUF_MIN_SIZE)
+			grbuf_size = PWBUF_MIN_SIZE;
+		grbuf = i_realloc(grbuf, old_grbuf_size, grbuf_size);
 	}
 }
 
@@ -54,8 +46,11 @@
 {
 	struct passwd *result;
 
-	pw_init();
-	errno = getpwnam_r(name, pwd_r, pwbuf, pwbuf_size, &result);
+	errno = 0;
+	do {
+		pw_init();
+		errno = getpwnam_r(name, pwd_r, pwbuf, pwbuf_size, &result);
+	} while (errno == ERANGE);
 	if (result != NULL)
 		return 1;
 	return errno == 0 ? 0 : -1;
@@ -65,8 +60,11 @@
 {
 	struct passwd *result;
 
-	pw_init();
-	errno = getpwuid_r(uid, pwd_r, pwbuf, pwbuf_size, &result);
+	errno = 0;
+	do {
+		pw_init();
+		errno = getpwuid_r(uid, pwd_r, pwbuf, pwbuf_size, &result);
+	} while (errno == ERANGE);
 	if (result != NULL)
 		return 1;
 	return errno == 0 ? 0 : -1;
@@ -76,8 +74,11 @@
 {
 	struct group *result;
 
-	gr_init();
-	errno = getgrnam_r(name, grp_r, grbuf, grbuf_size, &result);
+	errno = 0;
+	do {
+		gr_init();
+		errno = getgrnam_r(name, grp_r, grbuf, grbuf_size, &result);
+	} while (errno == ERANGE);
 	if (result != NULL)
 		return 1;
 	return errno == 0 ? 0 : -1;
@@ -87,8 +88,11 @@
 {
 	struct group *result;
 
-	gr_init();
-	errno = getgrgid_r(gid, grp_r, grbuf, grbuf_size, &result);
+	errno = 0;
+	do {
+		gr_init();
+		errno = getgrgid_r(gid, grp_r, grbuf, grbuf_size, &result);
+	} while (errno == ERANGE);
 	if (result != NULL)
 		return 1;
 	return errno == 0 ? 0 : -1;


More information about the dovecot-cvs mailing list