summaryrefslogtreecommitdiff
path: root/lib/fprint.c
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2012-09-19 13:01:59 +0300
committerPanu Matilainen <pmatilai@redhat.com>2012-09-19 13:14:21 +0300
commit921be290fc5d9479a554936d5b3c546154af1871 (patch)
tree08fec18371847aa689e1eae7f5b4a64ef93bdd66 /lib/fprint.c
parent0c1e3ec94df2b769fb2d6b77dbe5eca5e41f3d09 (diff)
downloadrpm-921be290fc5d9479a554936d5b3c546154af1871.tar.gz
Eliminate strdup() in doLookupId()
- Take advantage of the length-aware pool string->id lookup to avoid the need to copy and locally modify the canonized dirname. Makes the code cleaner and a little bit faster too. - There are further possibilities in this direction, canonDir() could return an id instead of malloced memory but that doesn't remove the need for temporary bugg^H^Hffer to clean up the dir.
Diffstat (limited to 'lib/fprint.c')
-rw-r--r--lib/fprint.c34
1 files changed, 14 insertions, 20 deletions
diff --git a/lib/fprint.c b/lib/fprint.c
index 8cb68e83a..04344506f 100644
--- a/lib/fprint.c
+++ b/lib/fprint.c
@@ -174,31 +174,24 @@ static int doLookupId(fingerPrintCache cache,
rpmsid dirNameId, rpmsid baseNameId,
fingerPrint *fp)
{
- char * end; /* points to the '\0' at the end of "buf" */
struct stat sb;
- char *buf = NULL;
const struct fprintCacheEntry_s * cacheHit;
char *cdn = canonDir(cache->pool, dirNameId);
- const char *rootDir = "/";
- size_t cdnl;
-
- memset(fp, 0, sizeof(*fp));
+ rpmsid fpId;
+ size_t fpLen;
+
if (cdn == NULL) goto exit; /* XXX only if realpath() above fails */
- cdnl = strlen(cdn);
- buf = xstrdup(cdn);
- end = buf + cdnl;
+ memset(fp, 0, sizeof(*fp));
+ fpId = rpmstrPoolId(cache->pool, cdn, 1);
+ fpLen = rpmstrPoolStrlen(cache->pool, fpId);;
while (1) {
- /* buf contents change through end ptr, requiring rehash on each loop */
- const char *fpDir = (*buf != '\0') ? buf : rootDir;
- rpmsid fpId = rpmstrPoolId(cache->pool, fpDir, 1);
-
/* as we're stating paths here, we want to follow symlinks */
cacheHit = cacheContainsDirectory(cache, fpId);
if (cacheHit != NULL) {
fp->entry = cacheHit;
- } else if (!stat(fpDir, &sb)) {
+ } else if (!stat(rpmstrPoolStr(cache->pool, fpId), &sb)) {
struct fprintCacheEntry_s * newEntry = xmalloc(sizeof(* newEntry));
newEntry->ino = sb.st_ino;
@@ -210,7 +203,7 @@ static int doLookupId(fingerPrintCache cache,
}
if (fp->entry) {
- const char * subDir = cdn + (end - buf) - 1;
+ const char * subDir = cdn + fpLen - 1;
/* XXX don't bother saving '/' as subdir */
if (subDir[0] == '\0' || (subDir[0] == '/' && subDir[1] == '\0'))
subDir = NULL;
@@ -221,16 +214,17 @@ static int doLookupId(fingerPrintCache cache,
}
/* stat of '/' just failed! */
- if (fpDir == rootDir)
+ if (fpLen == 1)
abort();
- end--;
- while ((end > buf) && *(end-1) != '/') end--;
- *end = '\0';
+ /* Find the parent directory and its id for the next round */
+ fpLen--;
+ while (fpLen > 1 && cdn[fpLen-1] != '/')
+ fpLen--;
+ fpId = rpmstrPoolIdn(cache->pool, cdn, fpLen, 1);
}
exit:
- free(buf);
free(cdn);
/* XXX TODO: failure from eg realpath() should be returned and handled */
return 0;