"Module":"talloc",
"Title":"talloc - tree allocator routines",
"Author":"dinesh",
"Dependencies":[
{
"depends":"ccan/typesafe_cb"
},
]
"Description":[
{
"str":""
},
{
"str":"Talloc is a hierarchical memory pool system with destructors: you keep your"
},
{
"str":"objects in heirarchies reflecting their lifetime.  Every pointer returned"
},
{
"str":"from talloc() is itself a valid talloc context, from which other talloc()s"
},
{
"str":"can be attached.  This means you can do this:"
},
{
"str":""
},
{
"str":" struct foo *X = talloc(mem_ctx, struct foo);"
},
{
"str":" X->name = talloc_strdup(X, "foo");"
},
{
"str":""
},
{
"str":"and the pointer X->name would be a "child" of the talloc context "X" which"
},
{
"str":"is itself a child of mem_ctx.  So if you do talloc_free(mem_ctx) then it is"
},
{
"str":"all destroyed, whereas if you do talloc_free(X) then just X and X->name are"
},
{
"str":"destroyed, and if you do talloc_free(X->name) then just the name element of"
},
{
"str":"X is destroyed."
},
{
"str":""
},
{
"str":"If you think about this, then what this effectively gives you is an n-ary"
},
{
"str":"tree, where you can free any part of the tree with talloc_free()."
},
{
"str":""
},
{
"str":"Talloc has been measured with a time overhead of around 4% over glibc"
},
{
"str":"malloc, and 48/80 bytes per allocation (32/64 bit)."
},
{
"str":""
},
{
"str":"This version is based on svn://svnanon.samba.org/samba/branches/SAMBA_4_0/source/lib/talloc revision 23158."
},
{
"str":""
},
{
"str":"Example:"
},
{
"str":"	#include <stdio.h>"
},
{
"str":"	#include <stdarg.h>"
},
{
"str":"	#include <err.h>"
},
{
"str":"	#include "talloc/talloc.h""
},
{
"str":""
},
{
"str":"	// A structure containing a popened comman."
},
{
"str":"	struct command"
},
{
"str":"	{"
},
{
"str":"		FILE *f;"
},
{
"str":"		const char *command;"
},
{
"str":"	};"
},
{
"str":""
},
{
"str":"	// When struct command is freed, we also want to pclose pipe."
},
{
"str":"	static int close_cmd(struct command *cmd)"
},
{
"str":"	{"
},
{
"str":"		pclose(cmd->f);"
},
{
"str":"		// 0 means "we succeeded, continue freeing""
},
{
"str":"		return 0;"
},
{
"str":"	}"
},
{
"str":""
},
{
"str":"	// This function opens a writable pipe to the given command."
},
{
"str":"	struct command *open_output_cmd(const void *ctx, char *fmt, ...)"
},
{
"str":"	{"
},
{
"str":"		va_list ap;"
},
{
"str":"		struct command *cmd = talloc(ctx, struct command);"
},
{
"str":""
},
{
"str":"		if (!cmd)"
},
{
"str":"			return NULL;"
},
{
"str":""
},
{
"str":"		va_start(ap, fmt);"
},
{
"str":"		cmd->command = talloc_vasprintf(cmd, fmt, ap);"
},
{
"str":"		va_end(ap);"
},
{
"str":"		if (!cmd->command) {"
},
{
"str":"			talloc_free(cmd);"
},
{
"str":"			return NULL;"
},
{
"str":"		}"
},
{
"str":""
},
{
"str":"		cmd->f = popen(cmd->command, "w");"
},
{
"str":"		if (!cmd->f) {"
},
{
"str":"			talloc_free(cmd);"
},
{
"str":"			return NULL;"
},
{
"str":"		}"
},
{
"str":"		talloc_set_destructor(cmd, close_cmd);"
},
{
"str":"		return cmd;"
},
{
"str":"	}"
},
{
"str":""
},
{
"str":"	int main(int argc, char *argv[])"
},
{
"str":"	{"
},
{
"str":"		struct command *cmd;"
},
{
"str":""
},
{
"str":"		if (argc != 2)"
},
{
"str":"			errx(1, "Usage: %s <command>\n");"
},
{
"str":""
},
{
"str":"		cmd = open_output_cmd(NULL, "%s hello", argv[1]);"
},
{
"str":"		if (!cmd)"
},
{
"str":"			err(1, "Running '%s hello'", argv[1]);"
},
{
"str":"		fprintf(cmd->f, "This is a test\n");"
},
{
"str":"		talloc_free(cmd);"
},
{
"str":"		return 0;"
},
{
"str":"	}"
},
]
