aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2006-11-24 14:57:31 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2006-11-24 14:57:31 +0000
commitc50f370f98e5f5d24d18ca3df444770dacce1824 (patch)
tree45516e35a895fa4eccfb36ff0d8c1e29714a2c41
parent4fbb584a0e6ee086d6b30936c7124c687b3e977f (diff)
downloadbusybox-c50f370f98e5f5d24d18ca3df444770dacce1824.tar.gz
tar: cache [ug]id->username/groupname mappings. Cuts down amount
of open/read/close of /etc/passwd and /etc/group dramatically (we were rereading those for each untarred file!!!)
-rw-r--r--archival/tar.c9
-rw-r--r--include/libbb.h1
-rw-r--r--libbb/procps.c66
3 files changed, 52 insertions, 24 deletions
diff --git a/archival/tar.c b/archival/tar.c
index 99c4adb6a..51d34ea19 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -211,12 +211,9 @@ static int writeTarHeader(struct TarBallInfo *tbInfo,
putOctal(header.mtime, sizeof(header.mtime), statbuf->st_mtime);
strcpy(header.magic, "ustar ");
- /* Enter the user and group names (default to root if it fails) */
-//cache!!!
- if (bb_getpwuid(header.uname, statbuf->st_uid, sizeof(header.uname)) == NULL)
- strcpy(header.uname, "root");
- if (bb_getgrgid(header.gname, statbuf->st_gid, sizeof(header.gname)) == NULL)
- strcpy(header.gname, "root");
+ /* Enter the user and group names */
+ safe_strncpy(header.uname, get_cached_username(statbuf->st_uid), sizeof(header.uname));
+ safe_strncpy(header.gname, get_cached_groupname(statbuf->st_gid), sizeof(header.gname));
if (tbInfo->hlInfo) {
/* This is a hard link */
diff --git a/include/libbb.h b/include/libbb.h
index 582e34f52..99a1928df 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -567,6 +567,7 @@ pid_t *find_pid_by_name(const char* procName);
pid_t *pidlist_reverse(pid_t *pidList);
void clear_username_cache(void);
const char* get_cached_username(uid_t uid);
+const char* get_cached_groupname(gid_t gid);
extern const char bb_uuenc_tbl_base64[];
diff --git a/libbb/procps.c b/libbb/procps.c
index dee5638e4..52203ee9a 100644
--- a/libbb/procps.c
+++ b/libbb/procps.c
@@ -11,32 +11,62 @@
#include "libbb.h"
-typedef struct {
- uid_t uid;
- char username[12];
-} user_map_t;
+typedef struct unsigned_to_name_map_t {
+ unsigned id;
+ char name[12];
+} unsigned_to_name_map_t;
-static user_map_t *username_cache;
-static int username_cache_size;
+typedef struct cache_t {
+ unsigned_to_name_map_t *cache;
+ int size;
+} cache_t;
+static cache_t username, groupname;
+
+static void clear_cache(cache_t *cp)
+{
+ free(cp->cache);
+ cp->cache = NULL;
+ cp->size = 0;
+}
void clear_username_cache(void)
{
- free(username_cache);
- username_cache = NULL;
- username_cache_size = 0;
+ clear_cache(&username);
+ clear_cache(&groupname);
}
-const char* get_cached_username(uid_t uid)
+/* Returns -N-1 if not found. */
+/* cp->cache[N] is allocated and must be filled in this case */
+static int get_cached(cache_t *cp, unsigned id)
{
int i;
- for (i = 0; i < username_cache_size; i++)
- if (username_cache[i].uid == uid)
- return username_cache[i].username;
- i = username_cache_size++;
- username_cache = xrealloc(username_cache, username_cache_size * sizeof(*username_cache));
- username_cache[i].uid = uid;
- bb_getpwuid(username_cache[i].username, uid, sizeof(username_cache[i].username));
- return username_cache[i].username;
+ for (i = 0; i < cp->size; i++)
+ if (cp->cache[i].id == id)
+ return i;
+ i = cp->size++;
+ cp->cache = xrealloc(cp->cache, cp->size * sizeof(*cp->cache));
+ cp->cache[i++].id = id;
+ return -i;
+}
+const char* get_cached_username(uid_t uid)
+{
+ int i = get_cached(&username, uid);
+ if (i < 0) {
+ i = -i - 1;
+ bb_getpwuid(username.cache[i].name, uid,
+ sizeof(username.cache[i].name));
+ }
+ return username.cache[i].name;
+}
+const char* get_cached_groupname(uid_t uid)
+{
+ int i = get_cached(&groupname, uid);
+ if (i < 0) {
+ i = -i - 1;
+ bb_getgrgid(groupname.cache[i].name, uid,
+ sizeof(groupname.cache[i].name));
+ }
+ return username.cache[i].name;
}