summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2017-08-17 17:04:48 +0200
committerYorhel <git@yorhel.nl>2017-08-17 17:04:48 +0200
commita830f7dfa6d40d9c90dfdd9adbd190ecce936d6c (patch)
tree05f1eb8143e1d37cdfce00adff11db2db307078a
parent3b55f8c137d7538e86c879c07b80ed6392cd862f (diff)
Use C99 flexible array member for struct dir
This should fix https://dev.yorhel.nl/ncdu/bug/99 - with the downside that this requires a C99 compiler. I also replaced all occurrences of static allocation of struct dir with use dynamic allocation, because I wasn't really sure if static allocation of flexible structs is allowed. In the case of dirlist.c the dynamic allocation is likely required anyway, because it does store a few bytes in the name field.
-rw-r--r--src/dir_import.c7
-rw-r--r--src/dirlist.c10
-rw-r--r--src/global.h2
3 files changed, 11 insertions, 8 deletions
diff --git a/src/dir_import.c b/src/dir_import.c
index 48a9e82..68c39fe 100644
--- a/src/dir_import.c
+++ b/src/dir_import.c
@@ -431,10 +431,13 @@ static int itemdir(uint64_t dev) {
static int iteminfo(struct dir **item, uint64_t dev, int isdir) {
- static struct dir dir;
- struct dir *tmp, *d = &dir;
+ static struct dir *dirbuf;
+ struct dir *tmp, *d;
uint64_t iv;
+ if(!dirbuf)
+ dirbuf = malloc(sizeof(struct dir));
+ d = dirbuf;
memset(d, 0, sizeof(struct dir));
d->flags |= isdir ? FF_DIR : FF_FILE;
d->dev = dev;
diff --git a/src/dirlist.c b/src/dirlist.c
index 50b90f0..893382c 100644
--- a/src/dirlist.c
+++ b/src/dirlist.c
@@ -40,8 +40,7 @@ int dirlist_sort_desc = 1,
dirlist_hidden = 0;
/* private state vars */
-static struct dir dirlist_parent_alloc;
-static struct dir *head, *head_real, *selected, *top = NULL;
+static struct dir *parent_alloc, *head, *head_real, *selected, *top = NULL;
@@ -206,14 +205,15 @@ void dirlist_open(struct dir *d) {
head_real = head = dirlist_sort(head);
/* set the reference to the parent dir */
- dirlist_parent_alloc.flags &= ~FF_BSEL;
- dirlist_parent_alloc.flags |= FF_DIR;
if(d->parent) {
- dirlist_parent = &dirlist_parent_alloc;
+ if(!parent_alloc)
+ parent_alloc = calloc(1, SDIRSIZE + 3);
+ dirlist_parent = parent_alloc;
strcpy(dirlist_parent->name, "..");
dirlist_parent->next = head;
dirlist_parent->parent = d;
dirlist_parent->sub = d;
+ dirlist_parent->flags = FF_DIR;
head = dirlist_parent;
} else
dirlist_parent = NULL;
diff --git a/src/global.h b/src/global.h
index 4cd02e1..8c02461 100644
--- a/src/global.h
+++ b/src/global.h
@@ -66,7 +66,7 @@ struct dir {
struct dir *parent, *next, *prev, *sub, *hlnk;
int items;
unsigned char flags;
- char name[3]; /* must be large enough to hold ".." */
+ char name[];
};
/* sizeof(total dir) = SDIRSIZE + strlen(name) = offsetof(struct dir, name) + strlen(name) + 1 */
#define SDIRSIZE (offsetof(struct dir, name)+1)