summaryrefslogtreecommitdiffstats
path: root/bftw.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2015-08-31 14:17:34 -0400
committerTavian Barnes <tavianator@tavianator.com>2015-08-31 14:17:34 -0400
commit5c22e106a7c1aa8cf11fc023ad0bdd3a6fb34030 (patch)
tree57935e7ed4ede48d4c2ac1f192a3b517067b53dc /bftw.c
parent0a281f1a541c210fbf7f1e8712b1e50874a82fb9 (diff)
downloadbfs-5c22e106a7c1aa8cf11fc023ad0bdd3a6fb34030.tar.xz
bftw: Store the paths with a trailing slash.
Diffstat (limited to 'bftw.c')
-rw-r--r--bftw.c69
1 files changed, 37 insertions, 32 deletions
diff --git a/bftw.c b/bftw.c
index 9b6f8b3..b7b5da6 100644
--- a/bftw.c
+++ b/bftw.c
@@ -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);