diff --git a/libisofs/find.c b/libisofs/find.c index 0288113..85acfca 100644 --- a/libisofs/find.c +++ b/libisofs/find.c @@ -134,6 +134,11 @@ int iso_dir_find_children(IsoDir* dir, IsoFindCondition *cond, data->iter = children; data->cond = cond; it->data = data; + + if (iso_dir_iter_register(it) < 0) { + free(it); + return ISO_OUT_OF_MEM; + } *iter = it; return ISO_SUCCESS; diff --git a/libisofs/node.c b/libisofs/node.c index 22f46d7..5def3a8 100644 --- a/libisofs/node.c +++ b/libisofs/node.c @@ -639,6 +639,11 @@ int iso_dir_get_children(const IsoDir *dir, IsoDirIter **iter) data->pos = NULL; data->flag = 0x00; it->data = data; + + if (iso_dir_iter_register(it) < 0) { + free(it); + return ISO_OUT_OF_MEM; + } *iter = it; return ISO_SUCCESS; @@ -663,6 +668,7 @@ int iso_dir_iter_has_next(IsoDirIter *iter) void iso_dir_iter_free(IsoDirIter *iter) { if (iter != NULL) { + iso_dir_iter_unregister(iter); iter->class->free(iter); free(iter); } @@ -970,6 +976,51 @@ int iso_dir_insert(IsoDir *dir, IsoNode *node, IsoNode **pos, return ++dir->nchildren; } +/* iterators are stored in a linked list */ +struct iter_reg_node { + IsoDirIter *iter; + struct iter_reg_node *next; +}; + +/* list header */ +static +struct iter_reg_node *iter_reg = NULL; + +/** + * Add a new iterator to the registry. The iterator register keeps track of + * all iterators being used, and are notified when directory structure + * changes. + */ +int iso_dir_iter_register(IsoDirIter *iter) +{ + struct iter_reg_node *new; + new = malloc(sizeof(struct iter_reg_node)); + if (new == NULL) { + return ISO_OUT_OF_MEM; + } + new->iter = iter; + new->next = iter_reg; + iter_reg = new; + return ISO_SUCCESS; +} + +/** + * Unregister a directory iterator. + */ +void iso_dir_iter_unregister(IsoDirIter *iter) +{ + struct iter_reg_node **pos; + pos = &iter_reg; + while (*pos != NULL && (*pos)->iter != iter) { + pos = &(*pos)->next; + } + if (*pos) { + struct iter_reg_node *tmp = (*pos)->next; + free(*pos); + *pos = tmp; + } +} + int iso_node_new_root(IsoDir **root) { IsoDir *dir; diff --git a/libisofs/node.h b/libisofs/node.h index a1fc96d..821a120 100644 --- a/libisofs/node.h +++ b/libisofs/node.h @@ -322,4 +322,18 @@ int iso_dir_exists(IsoDir *dir, const char *name, IsoNode ***pos); int iso_dir_insert(IsoDir *dir, IsoNode *node, IsoNode **pos, enum iso_replace_mode replace); +/** + * Add a new iterator to the registry. The iterator register keeps track of + * all iterators being used, and are notified when directory structure + * changes. + */ +int iso_dir_iter_register(IsoDirIter *iter); + +/** + * Unregister a directory iterator. + */ +void iso_dir_iter_unregister(IsoDirIter *iter); + + + #endif /*LIBISO_NODE_H_*/