From d7be81367997536dceb08a7be0014136a1f89df2 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Wed, 19 Apr 2023 20:08:47 +0200 Subject: libfstree: Make hard link resolution non-recursive Use the next_by_type pointer to create a list of all unresolved hard links and iterate over that list for link resolution. Signed-off-by: David Oberhollenzer --- lib/fstree/src/hardlink.c | 47 +++++++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 26 deletions(-) (limited to 'lib/fstree/src/hardlink.c') diff --git a/lib/fstree/src/hardlink.c b/lib/fstree/src/hardlink.c index 6973b4c..81636c7 100644 --- a/lib/fstree/src/hardlink.c +++ b/lib/fstree/src/hardlink.c @@ -53,31 +53,6 @@ static int resolve_link(fstree_t *fs, tree_node_t *node) return 0; } -static int resolve_hard_links_dfs(fstree_t *fs, tree_node_t *n) -{ - tree_node_t *it; - - if (n->mode == FSTREE_MODE_HARD_LINK) { - if (resolve_link(fs, n)) - goto fail_link; - } else if (S_ISDIR(n->mode)) { - for (it = n->data.children; it != NULL; it = it->next) { - if (resolve_hard_links_dfs(fs, it)) - return -1; - } - } - - return 0; -fail_link: { - char *path = fstree_get_path(n); - fprintf(stderr, "Resolving hard link '%s' -> '%s': %s\n", - path == NULL ? n->name : path, n->data.target, - strerror(errno)); - free(path); -} - return -1; -} - tree_node_t *fstree_add_hard_link(fstree_t *fs, const char *path, const char *target) { @@ -98,10 +73,30 @@ tree_node_t *fstree_add_hard_link(fstree_t *fs, const char *path, n->mode = FSTREE_MODE_HARD_LINK; } + n->next_by_type = fs->links_unresolved; + fs->links_unresolved = n; + return n; } int fstree_resolve_hard_links(fstree_t *fs) { - return resolve_hard_links_dfs(fs, fs->root); + while (fs->links_unresolved != NULL) { + tree_node_t *n = fs->links_unresolved; + + if (resolve_link(fs, n)) { + char *path = fstree_get_path(n); + fprintf(stderr, + "Resolving hard link '%s' -> '%s': %s\n", + path == NULL ? n->name : path, n->data.target, + strerror(errno)); + free(path); + return -1; + } + + fs->links_unresolved = n->next_by_type; + n->next_by_type = NULL; + } + + return 0; } -- cgit v1.2.3