diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2015-08-31 14:17:34 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2015-08-31 14:17:34 -0400 |
commit | 5c22e106a7c1aa8cf11fc023ad0bdd3a6fb34030 (patch) | |
tree | 57935e7ed4ede48d4c2ac1f192a3b517067b53dc /bftw.c | |
parent | 0a281f1a541c210fbf7f1e8712b1e50874a82fb9 (diff) | |
download | bfs-5c22e106a7c1aa8cf11fc023ad0bdd3a6fb34030.tar.xz |
bftw: Store the paths with a trailing slash.
Diffstat (limited to 'bftw.c')
-rw-r--r-- | bftw.c | 69 |
1 files changed, 37 insertions, 32 deletions
@@ -134,33 +134,46 @@ static void dircache_init(dircache *cache, size_t lru_size) { /** Add an entry to the dircache. */ static dircache_entry *dircache_add(dircache *cache, dircache_entry *parent, const char *name) { - size_t namesize = strlen(name) + 1; - dircache_entry *entry = malloc(sizeof(dircache_entry) + namesize); - if (entry) { - entry->parent = parent; - - if (parent) { - entry->depth = parent->depth + 1; - entry->nameoff = parent->nameoff + parent->namelen; - if (parent->namelen > 0 && parent->name[parent->namelen - 1] != '/') { - ++entry->nameoff; - } - } else { - entry->depth = 0; - entry->nameoff = 0; - } + size_t namelen = strlen(name); + size_t size = sizeof(dircache_entry) + namelen + 1; - entry->lru_prev = entry->lru_next = NULL; - entry->dir = NULL; - entry->refcount = 1; - entry->namelen = namesize - 1; - memcpy(entry->name, name, namesize); + bool needs_slash = false; + if (namelen == 0 || name[namelen - 1] != '/') { + needs_slash = true; + ++size; + } - while (parent) { - ++parent->refcount; - parent = parent->parent; - } + dircache_entry *entry = malloc(size); + if (!entry) { + return NULL; } + + entry->parent = parent; + + if (parent) { + entry->depth = parent->depth + 1; + entry->nameoff = parent->nameoff + parent->namelen; + } else { + entry->depth = 0; + entry->nameoff = 0; + } + + entry->lru_prev = entry->lru_next = NULL; + entry->dir = NULL; + entry->refcount = 1; + + memcpy(entry->name, name, namelen); + if (needs_slash) { + entry->name[namelen++] = '/'; + } + entry->name[namelen] = '\0'; + entry->namelen = namelen; + + while (parent) { + ++parent->refcount; + parent = parent->parent; + } + return entry; } @@ -235,9 +248,6 @@ static DIR *opendirat(int fd, const char *name) { static int dircache_entry_path(dircache_entry *entry, dynstr *path) { size_t namelen = entry->namelen; size_t pathlen = entry->nameoff + namelen; - if (namelen > 0 && entry->name[namelen - 1] != '/') { - ++pathlen; - } if (dynstr_grow(path, pathlen) != 0) { return -1; @@ -250,12 +260,7 @@ static int dircache_entry_path(dircache_entry *entry, dynstr *path) { do { char *segment = path->str + entry->nameoff; namelen = entry->namelen; - memcpy(segment, entry->name, namelen); - if (namelen > 0 && entry->name[namelen - 1] != '/') { - segment[namelen] = '/'; - } - entry = entry->parent; } while (entry); |