From owner-svn-src-head@FreeBSD.ORG Fri Apr 17 01:01:16 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 198E9106566C; Fri, 17 Apr 2009 01:01:16 +0000 (UTC) (envelope-from kientzle@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 06BAF8FC12; Fri, 17 Apr 2009 01:01:16 +0000 (UTC) (envelope-from kientzle@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n3H11Fwm099653; Fri, 17 Apr 2009 01:01:15 GMT (envelope-from kientzle@svn.freebsd.org) Received: (from kientzle@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n3H11FYi099652; Fri, 17 Apr 2009 01:01:15 GMT (envelope-from kientzle@svn.freebsd.org) Message-Id: <200904170101.n3H11FYi099652@svn.freebsd.org> From: Tim Kientzle Date: Fri, 17 Apr 2009 01:01:15 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r191178 - head/lib/libarchive X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 17 Apr 2009 01:01:17 -0000 Author: kientzle Date: Fri Apr 17 01:01:15 2009 New Revision: 191178 URL: http://svn.freebsd.org/changeset/base/191178 Log: Dynamically size the buffer we pass to getgrgid_r() and getpwuid_r(). Keep the buffer in the cache object so we don't have to keep doing this. Modified: head/lib/libarchive/archive_read_disk_set_standard_lookup.c Modified: head/lib/libarchive/archive_read_disk_set_standard_lookup.c ============================================================================== --- head/lib/libarchive/archive_read_disk_set_standard_lookup.c Fri Apr 17 01:00:11 2009 (r191177) +++ head/lib/libarchive/archive_read_disk_set_standard_lookup.c Fri Apr 17 01:01:15 2009 (r191178) @@ -61,6 +61,8 @@ static const char * const NO_NAME = "(no struct name_cache { struct archive *archive; + char *buff; + size_t buff_size; int probes; int hits; size_t size; @@ -73,8 +75,8 @@ struct name_cache { static const char * lookup_gname(void *, gid_t); static const char * lookup_uname(void *, uid_t); static void cleanup(void *); -static const char * lookup_gname_helper(struct archive *, id_t gid); -static const char * lookup_uname_helper(struct archive *, id_t uid); +static const char * lookup_gname_helper(struct name_cache *, id_t gid); +static const char * lookup_uname_helper(struct name_cache *, id_t uid); /* * Installs functions that use getpwuid()/getgrgid()---along with @@ -128,6 +130,7 @@ cleanup(void *data) cache->cache[i].name != NO_NAME) free((void *)(uintptr_t)cache->cache[i].name); } + free(cache->buff); free(cache); } } @@ -137,7 +140,7 @@ cleanup(void *data) */ static const char * lookup_name(struct name_cache *cache, - const char * (*lookup_fn)(struct archive *, id_t), id_t id) + const char * (*lookup_fn)(struct name_cache *, id_t), id_t id) { const char *name; int slot; @@ -158,7 +161,7 @@ lookup_name(struct name_cache *cache, cache->cache[slot].name = NULL; } - name = (lookup_fn)(cache->archive, id); + name = (lookup_fn)(cache, id); if (name == NULL) { /* Cache and return the negative response. */ cache->cache[slot].name = NO_NAME; @@ -180,23 +183,43 @@ lookup_uname(void *data, uid_t uid) } static const char * -lookup_uname_helper(struct archive *a, id_t id) +lookup_uname_helper(struct name_cache *cache, id_t id) { - char buffer[512]; struct passwd pwent, *result; int r; - errno = 0; - r = getpwuid_r((uid_t)id, &pwent, buffer, sizeof(buffer), &result); + if (cache->buff_size == 0) { + cache->buff_size = 256; + cache->buff = malloc(cache->buff_size); + } + if (cache->buff == NULL) + return (NULL); + for (;;) { + r = getpwuid_r((uid_t)id, &pwent, + cache->buff, cache->buff_size, &result); + if (r == 0) + break; + if (r != ERANGE) + break; + /* ERANGE means our buffer was too small, but POSIX + * doesn't tell us how big the buffer should be, so + * we just double it and try again. Because the buffer + * is kept around in the cache object, we shouldn't + * have to do this very often. */ + cache->buff_size *= 2; + cache->buff = realloc(cache->buff, cache->buff_size); + if (cache->buff == NULL) + break; + } if (r != 0) { - archive_set_error(a, errno, + archive_set_error(cache->archive, errno, "Can't lookup user for id %d", (int)id); return (NULL); } if (result == NULL) return (NULL); - return strdup(pwent.pw_name); + return strdup(result->pw_name); } static const char * @@ -208,22 +231,40 @@ lookup_gname(void *data, gid_t gid) } static const char * -lookup_gname_helper(struct archive *a, id_t id) +lookup_gname_helper(struct name_cache *cache, id_t id) { - char buffer[512]; struct group grent, *result; int r; - errno = 0; - r = getgrgid_r((gid_t)id, &grent, buffer, sizeof(buffer), &result); + if (cache->buff_size == 0) { + cache->buff_size = 256; + cache->buff = malloc(cache->buff_size); + } + if (cache->buff == NULL) + return (NULL); + for (;;) { + r = getgrgid_r((gid_t)id, &grent, + cache->buff, cache->buff_size, &result); + if (r == 0) + break; + if (r != ERANGE) + break; + /* ERANGE means our buffer was too small, but POSIX + * doesn't tell us how big the buffer should be, so + * we just double it and try again. */ + cache->buff_size *= 2; + cache->buff = realloc(cache->buff, cache->buff_size); + if (cache->buff == NULL) + break; + } if (r != 0) { - archive_set_error(a, errno, + archive_set_error(cache->archive, errno, "Can't lookup group for id %d", (int)id); return (NULL); } if (result == NULL) return (NULL); - return strdup(grent.gr_name); + return strdup(result->gr_name); } #endif /* ! (_WIN32 && !__CYGWIN__) */