]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
i_get(pw|gr)(nam|uid): Use small initial buffer sizes.
authorTimo Sirainen <tss@iki.fi>
Tue, 11 Sep 2012 15:56:07 +0000 (18:56 +0300)
committerTimo Sirainen <tss@iki.fi>
Tue, 11 Sep 2012 15:56:07 +0000 (18:56 +0300)
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.

src/lib/ipwd.c

index 6b12ecf07217ac8eb06c39f295616165fcbb2f50..73ac276e61b8ce6d2daa87875d4eeade0de63d8f 100644 (file)
@@ -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;
-
-       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);
+       size_t old_grbuf_size = 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 @@ int i_getpwnam(const char *name, struct passwd *pwd_r)
 {
        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 @@ int i_getpwuid(uid_t uid, struct passwd *pwd_r)
 {
        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 @@ int i_getgrnam(const char *name, struct group *grp_r)
 {
        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 @@ int i_getgrgid(gid_t gid, struct group *grp_r)
 {
        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;