From 6aa77bc0efc27d976f2d478ca54fa59a7c47e934 Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Sun, 28 May 2023 18:38:52 -0700 Subject: til_setup,*: note settings path in til_setup_t This commit adds passing the settings instance to til_setup_new() which is used for deriving a path for the setup via til_settings_print_path() on the supplied settings. That path gets an allocated copy left in the returned til_setup_t at til_setup_t.path This path will exist for the lifetime of the til_setup_t, to be freed along with the rest of the baked setup instance when the refcount reaches 0. The incoming til_settings_t is only read @ til_setup_new() in constructing the path, no reference is kept. Basically the til_settings_t* is just passed in for convenience reasons, since constructing the path needs memory and may fail, this approach lets the existing til_setup_new() call error handling also capture the path allocation failures as-is turning til_setup_new() into a bit more of a convenience helper. Note that now all code may assume a til_setup_t has a set and valid til_setup_t.path, which should be useful for context creates when a setup is available. --- src/til_setup.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'src/til_setup.c') diff --git a/src/til_setup.c b/src/til_setup.c index d819173..c1198fd 100644 --- a/src/til_setup.c +++ b/src/til_setup.c @@ -1,7 +1,9 @@ #include #include +#include #include +#include "til_settings.h" #include "til_setup.h" @@ -10,20 +12,46 @@ * instance returned when destroyed. If free_func is NULL, free() will be * used by default. * + * A copy of the provided settings' path is stored at til_setup_t.path, and will + * always be freed automatically when the setup instance is freed, independent of + * free_func. + * * Note this returns void * despite creating a til_setup_t, this is for convenience * as the callers are generally using it in place of calloc(), and assign it to a * container struct of some other type but having an embedded til_setup_t. */ -void * til_setup_new(size_t size, void (*free_func)(til_setup_t *setup)) +void * til_setup_new(const til_settings_t *settings, size_t size, void (*free_func)(til_setup_t *setup)) { + char *path_buf = NULL; til_setup_t *setup; + assert(settings); assert(size >= sizeof(til_setup_t)); + { /* TODO FIXME: more unportable memstream use! */ + FILE *path_fp; + size_t path_sz; + int r; + + path_fp = open_memstream(&path_buf, &path_sz); + if (!path_fp) + return NULL; + + r = til_settings_print_path(settings, path_fp); + fclose(path_fp); + if (r < 0) { + free(path_buf); + return NULL; + } + } + setup = calloc(1, size); - if (!setup) + if (!setup) { + free(path_buf); return NULL; + } + setup->path = path_buf; setup->refcount = 1; setup->free = free_func; @@ -57,6 +85,9 @@ static void * til_setup_unref(til_setup_t *setup) setup->refcount--; if (!setup->refcount) { + /* don't make setup->free() free the path when provided */ + free((void *)setup->path); + if (setup->free) setup->free(setup); else -- cgit v1.2.1