From: Rusty Russell Date: Mon, 19 Nov 2012 02:22:41 +0000 (+1030) Subject: tal: make sure tal_free() preserves errno. X-Git-Url: http://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=34c2962d00c4ec24f248bddfd42f2e79cc6b61ef;ds=sidebyside tal: make sure tal_free() preserves errno. Always good form to have cleanup functions preserve errno. Signed-off-by: Rusty Russell --- diff --git a/ccan/tal/tal.c b/ccan/tal/tal.c index 474c0ff0..f33a069a 100644 --- a/ccan/tal/tal.c +++ b/ccan/tal/tal.c @@ -9,6 +9,7 @@ #include #include #include +#include //#define TAL_DEBUG 1 @@ -482,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; @@ -489,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) diff --git a/ccan/tal/tal.h b/ccan/tal/tal.h index da448d8f..a12e0dc4 100644 --- a/ccan/tal/tal.h +++ b/ccan/tal/tal.h @@ -58,6 +58,8 @@ typedef void tal_t; * * This calls the destructors for p (if any), then does the same for all its * children (recursively) before finally freeing the memory. + * + * Note: errno is preserved by this call. */ void tal_free(const tal_t *p); diff --git a/ccan/tal/test/run-free.c b/ccan/tal/test/run-free.c new file mode 100644 index 00000000..7b9a086e --- /dev/null +++ b/ccan/tal/test/run-free.c @@ -0,0 +1,25 @@ +#include +#include +#include + +static void destroy_errno(char *p) +{ + errno = ENOENT; +} + +int main(void) +{ + char *p; + + plan_tests(2); + + p = tal(NULL, char); + ok1(tal_add_destructor(p, destroy_errno)); + + /* Errno save/restored across free. */ + errno = EINVAL; + tal_free(p); + ok1(errno == EINVAL); + + return exit_status(); +}