]> git.ozlabs.org Git - ccan/blobdiff - ccan/tal/tal.c
tal: make tal_free() return NULL
[ccan] / ccan / tal / tal.c
index 0b5e8e445674720f288819c9d2370e1a80d14c64..5ab6cb682cd5349b060b8731e99d9f18c45bb15e 100644 (file)
@@ -493,18 +493,17 @@ static struct tal_hdr *remove_node(struct tal_hdr *t)
        return NULL;
 }
 
-void tal_free(const tal_t *ctx)
+void *tal_free(const tal_t *ctx)
 {
-        struct tal_hdr *t;
-       int saved_errno = errno;
-
-        if (!ctx)
-                return;
-
-        t = debug_tal(to_tal_hdr(ctx));
-        remove_node(t);
-        del_tree(t);
-       errno = saved_errno;
+        if (ctx) {
+               struct tal_hdr *t;
+               int saved_errno = errno;
+               t = debug_tal(to_tal_hdr(ctx));
+               remove_node(t);
+               del_tree(t);
+               errno = saved_errno;
+       }
+       return NULL;
 }
 
 void *tal_steal_(const tal_t *new_parent, const tal_t *ctx)
@@ -718,18 +717,26 @@ bool tal_resize_(tal_t **ctxp, size_t size)
 
 char *tal_strdup(const tal_t *ctx, const char *p)
 {
-       return tal_dup(ctx, char, p, strlen(p)+1, 0);
+       /* We have to let through NULL for take(). */
+       return tal_dup(ctx, char, p, p ? strlen(p) + 1: 1, 0);
 }
 
 char *tal_strndup(const tal_t *ctx, const char *p, size_t n)
 {
+       size_t len;
        char *ret;
 
-       if (strlen(p) < n)
-               n = strlen(p);
-       ret = tal_dup(ctx, char, p, n, 1);
+       /* We have to let through NULL for take(). */
+       if (likely(p)) {
+               len = strlen(p);
+               if (len > n)
+                       len = n;
+       } else
+               len = n;
+
+       ret = tal_dup(ctx, char, p, len, 1);
        if (ret)
-               ret[n] = '\0';
+               ret[len] = '\0';
        return ret;
 }
 
@@ -749,14 +756,10 @@ void *tal_dup_(const tal_t *ctx, const void *p, size_t n, size_t extra,
        if (taken(p)) {
                if (unlikely(!p))
                        return NULL;
-               if (unlikely(!tal_resize_((void **)&p, n + extra))) {
-                       tal_free(p);
-                       return NULL;
-               }
-               if (unlikely(!tal_steal(ctx, p))) {
-                       tal_free(p);
-                       return NULL;
-               }
+               if (unlikely(!tal_resize_((void **)&p, n + extra)))
+                       return tal_free(p);
+               if (unlikely(!tal_steal(ctx, p)))
+                       return tal_free(p);
                return (void *)p;
        }
        ret = tal_alloc_(ctx, n + extra, false, label);
@@ -779,10 +782,15 @@ char *tal_asprintf(const tal_t *ctx, const char *fmt, ...)
 
 char *tal_vasprintf(const tal_t *ctx, const char *fmt, va_list ap)
 {
-       size_t max = strlen(fmt) * 2;
+       size_t max;
        char *buf;
        int ret;
 
+       if (!fmt && taken(fmt))
+               return NULL;
+
+       /* A decent guess to start. */
+       max = strlen(fmt) * 2;
        buf = tal_arr(ctx, char, max);
        while (buf) {
                va_list ap2;
@@ -793,10 +801,8 @@ char *tal_vasprintf(const tal_t *ctx, const char *fmt, va_list ap)
 
                if (ret < max)
                        break;
-               if (!tal_resize(&buf, max *= 2)) {
-                       tal_free(buf);
-                       buf = NULL;
-               }
+               if (!tal_resize(&buf, max *= 2))
+                       buf = tal_free(buf);
        }
        if (taken(fmt))
                tal_free(fmt);