static void *(*resizefn)(void *, size_t size) = realloc;
static void (*freefn)(void *) = free;
static void (*errorfn)(const char *msg) = (void *)abort;
-static bool initialized = false;
/* Count on non-destrutor notifiers; often stays zero. */
static size_t notifiers = 0;
}
/* This means valgrind can see leaks. */
-static void tal_cleanup(void)
+void tal_cleanup(void)
{
struct tal_hdr *i;
- while ((i = list_top(&null_parent.c.children, struct tal_hdr, list)))
+ while ((i = list_top(&null_parent.c.children, struct tal_hdr, list))) {
list_del(&i->list);
+ memset(i, 0, sizeof(*i));
+ }
/* Cleanup any taken pointers. */
take_cleanup();
}
-/* For allocation failures inside ccan/take */
-static void take_alloc_failed(const void *p)
-{
- tal_free(p);
-}
-
/* We carefully start all real properties with a zero byte. */
static bool is_literal(const struct prop_hdr *prop)
{
struct children *children = find_property(parent, CHILDREN);
if (!children) {
- if (unlikely(!initialized)) {
- atexit(tal_cleanup);
- take_allocfail(take_alloc_failed);
- initialized = true;
- }
children = add_child_property(parent, child);
if (!children)
return false;
return from_tal_hdr(ignore_destroying_bit(t->parent_child)->parent);
}
-bool tal_resize_(tal_t **ctxp, size_t size, size_t count)
+bool tal_resize_(tal_t **ctxp, size_t size, size_t count, bool clear)
{
struct tal_hdr *old_t, *t;
struct children *child;
struct prop_hdr **lenp;
struct length len;
- size_t extra = 0;
+ size_t extra = 0, elemsize = size;
old_t = debug_tal(to_tal_hdr(*ctxp));
/* Copy here, in case we're shrinking! */
len = *(struct length *)*lenp;
extra = extra_for_length(size);
- }
+ } else /* If we don't have an old length, we can't clear! */
+ assert(!clear);
t = resizefn(old_t, sizeof(struct tal_hdr) + size + extra);
if (!t) {
if (lenp) {
struct length *new_len;
+ /* Clear between old end and new end. */
+ if (clear && count > len.count) {
+ char *old_end = (char *)(t + 1) + len.count * elemsize;
+ memset(old_end, 0, elemsize * (count - len.count));
+ }
+
new_len = (struct length *)((char *)(t + 1) + size);
len.count = count;
*new_len = len;
assert(src < *ctxp
|| (char *)src >= (char *)(*ctxp) + (size * old_count));
- if (!tal_resize_(ctxp, size, old_count + count))
+ if (!tal_resize_(ctxp, size, old_count + count, false))
goto out;
memcpy((char *)*ctxp + size * old_count, src, count * size);
if (taken(p)) {
if (unlikely(!p))
return NULL;
- if (unlikely(!tal_resize_((void **)&p, size, n + extra)))
+ if (unlikely(!tal_resize_((void **)&p, size, n + extra, false)))
return tal_free(p);
if (unlikely(!tal_steal(ctx, p)))
return tal_free(p);