summaryrefslogtreecommitdiff
path: root/src/til_setup.c
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2023-05-28 18:38:52 -0700
committerVito Caputo <vcaputo@pengaru.com>2023-05-28 18:38:52 -0700
commit6aa77bc0efc27d976f2d478ca54fa59a7c47e934 (patch)
treef59d6dc330014a747da94aa2f4d34618e8d6310d /src/til_setup.c
parentfc476199681664f4498babba674c209147fc041c (diff)
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.
Diffstat (limited to 'src/til_setup.c')
-rw-r--r--src/til_setup.c35
1 files changed, 33 insertions, 2 deletions
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 <assert.h>
#include <errno.h>
+#include <stdio.h>
#include <stdlib.h>
+#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
© All Rights Reserved