summaryrefslogtreecommitdiff
path: root/ccan/tal/_info
diff options
context:
space:
mode:
authorWilliam Casarin <jb55@jb55.com>2018-07-09 12:10:32 -0700
committerWilliam Casarin <jb55@jb55.com>2018-07-09 12:10:32 -0700
commit1b8fbbd843ddeb5fc81c9303db9c590a436d499b (patch)
treea7227dfe8e4fbaee7b1e0b58b24994dce8078f3f /ccan/tal/_info
parent37a9cdd2e80386f2c94e14e4f511284ae14c745a (diff)
progress
Diffstat (limited to 'ccan/tal/_info')
-rw-r--r--ccan/tal/_info108
1 files changed, 108 insertions, 0 deletions
diff --git a/ccan/tal/_info b/ccan/tal/_info
new file mode 100644
index 0000000..5285c16
--- /dev/null
+++ b/ccan/tal/_info
@@ -0,0 +1,108 @@
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+
+/**
+ * tal - compact tree allocator routines (inspired by talloc)
+ *
+ * Tal is a hierarchical allocator; any pointer allocated by tal can
+ * become the parent of another allocation. When you free that parent,
+ * the children (and grandchildren, etc) are automatically freed.
+ *
+ * This allows you to build complex objects based on their lifetimes, eg:
+ *
+ * struct foo *X = tal(NULL, struct foo);
+ * X->val = tal(X, int);
+ *
+ * and the pointer X->val would be a "child" of the tal context "X";
+ * tal_free(X->val) would free X->val as expected, by tal_free(X) would
+ * free X and X->val.
+ *
+ * With an overhead of approximately 4 pointers per object
+ * (vs. talloc's 12 pointers), it uses dynamic allocation for
+ * destructors and child lists, so those operations can fail. It does
+ * not support talloc's references or failing destructors.
+ *
+ * See Also:
+ * ccan/tal/str (useful string helpers)
+ *
+ * Example:
+ * #include <stdio.h>
+ * #include <err.h>
+ * #include <ccan/tal/tal.h>
+ *
+ * // A structure containing a popened command.
+ * struct command {
+ * FILE *f;
+ * char *command;
+ * };
+ *
+ * // When struct command is freed, we also want to pclose pipe.
+ * static void close_cmd(struct command *cmd)
+ * {
+ * pclose(cmd->f);
+ * }
+ *
+ * // This function opens a writable pipe to the given command.
+ * static struct command *open_output_cmd(const tal_t *ctx,
+ * const char *a0, const char *a1)
+ * {
+ * struct command *cmd = tal(ctx, struct command);
+ *
+ * if (!cmd)
+ * return NULL;
+ *
+ * // Note that tal/str has helpers to make this much easier!
+ * cmd->command = tal_arrz(cmd, char, strlen(a0) + strlen(a1) + 2);
+ * if (!cmd->command) {
+ * tal_free(cmd);
+ * return NULL;
+ * }
+ * strcat(cmd->command, a0);
+ * strcat(cmd->command, " ");
+ * strcat(cmd->command, a1);
+ *
+ * cmd->f = popen(cmd->command, "w");
+ * if (!cmd->f) {
+ * tal_free(cmd);
+ * return NULL;
+ * }
+ * tal_add_destructor(cmd, close_cmd);
+ * return cmd;
+ * }
+ *
+ * int main(int argc, char *argv[])
+ * {
+ * struct command *cmd;
+ *
+ * if (argc != 2)
+ * errx(1, "Usage: %s <command>\n", argv[0]);
+ *
+ * cmd = open_output_cmd(NULL, argv[1], "hello");
+ * if (!cmd)
+ * err(1, "Running '%s hello'", argv[1]);
+ * fprintf(cmd->f, "This is a test\n");
+ * tal_free(cmd);
+ * return 0;
+ * }
+ *
+ * License: BSD-MIT
+ */
+int main(int argc, char *argv[])
+{
+ if (argc != 2)
+ return 1;
+
+ if (strcmp(argv[1], "depends") == 0) {
+ printf("ccan/alignof\n");
+ printf("ccan/compiler\n");
+ printf("ccan/likely\n");
+ printf("ccan/list\n");
+ printf("ccan/str\n");
+ printf("ccan/take\n");
+ printf("ccan/typesafe_cb\n");
+ return 0;
+ }
+
+ return 1;
+}