X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftal%2Ftal.c;h=f33a069a4bf49af63932350aa236b513cfc912e4;hp=612c67bb833f65de486a3c0d534487efc761d85e;hb=34c2962d00c4ec24f248bddfd42f2e79cc6b61ef;hpb=da9f271b74088191908e69f01acfbe05c390a87f diff --git a/ccan/tal/tal.c b/ccan/tal/tal.c index 612c67bb..f33a069a 100644 --- a/ccan/tal/tal.c +++ b/ccan/tal/tal.c @@ -9,6 +9,7 @@ #include #include #include +#include //#define TAL_DEBUG 1 @@ -294,6 +295,7 @@ static struct children *add_child_property(struct tal_hdr *parent, init_group_property(&prop->group, prop, child); list_head_init(&prop->group.list); + update_bounds(&prop->group); } return prop; } @@ -316,8 +318,7 @@ static bool add_child(struct tal_hdr *parent, struct tal_hdr *child) children = add_child_property(parent, child); if (!children) return false; - children->group.list.n.next = children->group.list.n.prev - = &children->group.list.n; + list_head_init(&children->group.list); /* Child links to itself. */ child->next = child; @@ -455,6 +456,7 @@ static struct tal_hdr *remove_node(struct tal_hdr *t) /* Are we the only one? */ if (prev == t) { + struct prop_hdr *next = (*prop)->next; struct children *c = group->parent_child; /* Is this the group embedded in the child property? */ if (group == &c->group) { @@ -462,9 +464,9 @@ static struct tal_hdr *remove_node(struct tal_hdr *t) } else { /* Empty group, so free it. */ list_del_from(&c->group.list, &group->list.n); - *prop = group->hdr.next; freefn(group); } + *prop = next; return c->parent; } else { /* Move property to next node. */ @@ -481,6 +483,7 @@ static struct tal_hdr *remove_node(struct tal_hdr *t) void tal_free(const tal_t *ctx) { struct tal_hdr *t; + int saved_errno = errno; if (!ctx) return; @@ -488,6 +491,7 @@ void tal_free(const tal_t *ctx) t = debug_tal(to_tal_hdr(ctx)); remove_node(t); del_tree(t); + errno = saved_errno; } void *tal_steal_(const tal_t *new_parent, const tal_t *ctx) @@ -638,7 +642,12 @@ tal_t *tal_next(const tal_t *root, const tal_t *prev) tal_t *tal_parent(const tal_t *ctx) { struct group *group; - struct tal_hdr *t = debug_tal(to_tal_hdr(ctx)); + struct tal_hdr *t; + + if (!ctx) + return NULL; + + t = debug_tal(to_tal_hdr(ctx)); while (!(group = find_property(t, GROUP))) t = t->next; @@ -887,7 +896,8 @@ static bool check_node(struct group *group, name = (struct name *)p; break; } - if (p != &null_parent.c.hdr && !in_bounds(p)) + if (p != &null_parent.c.hdr && p != &null_parent.c.group.hdr + && !in_bounds(p)) return check_err(t, errorstr, "has bad property pointer");