2 Samba Unix SMB/CIFS implementation.
4 Samba trivial allocation library - new interface
6 NOTE: Please read talloc_guide.txt for full documentation
8 Copyright (C) Andrew Tridgell 2004
9 Copyright (C) Stefan Metzmacher 2006
11 ** NOTE! The following LGPL license applies to the talloc
12 ** library. This does NOT imply that all of Samba is released
15 This library is free software; you can redistribute it and/or
16 modify it under the terms of the GNU Lesser General Public
17 License as published by the Free Software Foundation; either
18 version 2 of the License, or (at your option) any later version.
20 This library is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 Lesser General Public License for more details.
25 You should have received a copy of the GNU Lesser General Public
26 License along with this library; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 inspired by http://swapped.cc/halloc/
39 /* use this to force every realloc to change the pointer, to stress test
40 code that might not cope */
41 #define ALWAYS_REALLOC 0
44 #define MAX_TALLOC_SIZE 0x10000000
45 #define TALLOC_MAGIC 0xe814ec70
46 #define TALLOC_FLAG_FREE 0x01
47 #define TALLOC_FLAG_LOOP 0x02
48 #define TALLOC_FLAG_EXT_ALLOC 0x04
49 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
51 /* by default we abort when given a bad pointer (such as when talloc_free() is called
52 on a pointer that came from malloc() */
54 #define TALLOC_ABORT(reason) abort()
57 #ifndef discard_const_p
58 #if defined(INTPTR_MIN)
59 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
61 # define discard_const_p(type, ptr) ((type *)(ptr))
65 /* these macros gain us a few percent of speed on gcc */
66 #if HAVE_BUILTIN_EXPECT
67 /* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
68 as its first argument */
69 #define likely(x) __builtin_expect(!!(x), 1)
70 #define unlikely(x) __builtin_expect(!!(x), 0)
76 /* this null_context is only used if talloc_enable_leak_report() or
77 talloc_enable_leak_report_full() is called, otherwise it remains
80 static void *null_context;
81 static void *autofree_context;
83 static void *(*tc_external_alloc)(void *parent, size_t size);
84 static void (*tc_external_free)(void *ptr, void *parent);
85 static void *(*tc_external_realloc)(void *ptr, void *parent, size_t size);
87 struct talloc_reference_handle {
88 struct talloc_reference_handle *next, *prev;
92 typedef int (*talloc_destructor_t)(void *);
95 struct talloc_chunk *next, *prev;
96 struct talloc_chunk *parent, *child;
97 struct talloc_reference_handle *refs;
98 talloc_destructor_t destructor;
104 /* 16 byte alignment seems to keep everyone happy */
105 #define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
106 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
108 /* panic if we get a bad magic value */
109 static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
111 const char *pp = (const char *)ptr;
112 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
113 if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) {
114 if (tc->flags & TALLOC_FLAG_FREE) {
115 TALLOC_ABORT("Bad talloc magic value - double free");
117 TALLOC_ABORT("Bad talloc magic value - unknown value");
123 /* hook into the front of the list */
124 #define _TLIST_ADD(list, p) \
128 (p)->next = (p)->prev = NULL; \
130 (list)->prev = (p); \
131 (p)->next = (list); \
137 /* remove an element from a list - element doesn't have to be in list. */
138 #define _TLIST_REMOVE(list, p) \
140 if ((p) == (list)) { \
141 (list) = (p)->next; \
142 if (list) (list)->prev = NULL; \
144 if ((p)->prev) (p)->prev->next = (p)->next; \
145 if ((p)->next) (p)->next->prev = (p)->prev; \
147 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
152 return the parent chunk of a pointer
154 static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr)
156 struct talloc_chunk *tc;
158 if (unlikely(ptr == NULL)) {
162 tc = talloc_chunk_from_ptr(ptr);
163 while (tc->prev) tc=tc->prev;
168 void *talloc_parent(const void *ptr)
170 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
171 return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
177 const char *talloc_parent_name(const void *ptr)
179 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
180 return tc? tc->name : NULL;
184 Allocate a bit of memory as a child of an existing pointer
186 static inline void *__talloc(const void *context, size_t size)
188 struct talloc_chunk *tc;
189 struct talloc_chunk *parent = NULL; /* Prevent spurious gcc warning */
190 unsigned flags = TALLOC_MAGIC;
192 if (unlikely(context == NULL)) {
193 context = null_context;
196 if (unlikely(size >= MAX_TALLOC_SIZE)) {
200 if (likely(context)) {
201 parent = talloc_chunk_from_ptr(context);
202 if (unlikely(parent->flags & TALLOC_FLAG_EXT_ALLOC)) {
203 tc = tc_external_alloc(TC_PTR_FROM_CHUNK(parent),
205 flags |= TALLOC_FLAG_EXT_ALLOC;
210 tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size);
212 if (unlikely(tc == NULL)) return NULL;
216 tc->destructor = NULL;
221 if (likely(context)) {
223 parent->child->parent = NULL;
224 tc->next = parent->child;
233 tc->next = tc->prev = tc->parent = NULL;
236 return TC_PTR_FROM_CHUNK(tc);
240 setup a destructor to be called on free of a pointer
241 the destructor should return 0 on success, or -1 on failure.
242 if the destructor fails then the free is failed, and the memory can
243 be continued to be used
245 void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
247 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
248 tc->destructor = destructor;
252 increase the reference count on a piece of memory.
254 int talloc_increase_ref_count(const void *ptr)
256 if (unlikely(!talloc_reference(null_context, ptr))) {
263 helper for talloc_reference()
265 this is referenced by a function pointer and should not be inline
267 static int talloc_reference_destructor(struct talloc_reference_handle *handle)
269 struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
270 _TLIST_REMOVE(ptr_tc->refs, handle);
275 more efficient way to add a name to a pointer - the name must point to a
278 static inline void _talloc_set_name_const(const void *ptr, const char *name)
280 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
285 internal talloc_named_const()
287 static inline void *_talloc_named_const(const void *context, size_t size, const char *name)
291 ptr = __talloc(context, size);
292 if (unlikely(ptr == NULL)) {
296 _talloc_set_name_const(ptr, name);
302 make a secondary reference to a pointer, hanging off the given context.
303 the pointer remains valid until both the original caller and this given
306 the major use for this is when two different structures need to reference the
307 same underlying data, and you want to be able to free the two instances separately,
310 void *_talloc_reference(const void *context, const void *ptr)
312 struct talloc_chunk *tc;
313 struct talloc_reference_handle *handle;
314 if (unlikely(ptr == NULL)) return NULL;
316 tc = talloc_chunk_from_ptr(ptr);
317 handle = (struct talloc_reference_handle *)_talloc_named_const(context,
318 sizeof(struct talloc_reference_handle),
319 TALLOC_MAGIC_REFERENCE);
320 if (unlikely(handle == NULL)) return NULL;
322 /* note that we hang the destructor off the handle, not the
323 main context as that allows the caller to still setup their
324 own destructor on the context if they want to */
325 talloc_set_destructor(handle, talloc_reference_destructor);
326 handle->ptr = discard_const_p(void, ptr);
327 _TLIST_ADD(tc->refs, handle);
333 internal talloc_free call
335 static inline int _talloc_free(void *ptr)
337 struct talloc_chunk *tc;
338 void *oldparent = NULL;
340 if (unlikely(ptr == NULL)) {
344 tc = talloc_chunk_from_ptr(ptr);
346 if (unlikely(tc->refs)) {
348 /* check this is a reference from a child or grantchild
349 * back to it's parent or grantparent
351 * in that case we need to remove the reference and
352 * call another instance of talloc_free() on the current
355 is_child = talloc_is_parent(tc->refs, ptr);
356 _talloc_free(tc->refs);
358 return _talloc_free(ptr);
363 if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) {
364 /* we have a free loop - stop looping */
368 if (unlikely(tc->destructor)) {
369 talloc_destructor_t d = tc->destructor;
370 if (d == (talloc_destructor_t)-1) {
373 tc->destructor = (talloc_destructor_t)-1;
378 tc->destructor = NULL;
382 oldparent = TC_PTR_FROM_CHUNK(tc->parent);
383 _TLIST_REMOVE(tc->parent->child, tc);
384 if (tc->parent->child) {
385 tc->parent->child->parent = tc->parent;
388 if (tc->prev) tc->prev->next = tc->next;
389 if (tc->next) tc->next->prev = tc->prev;
392 tc->flags |= TALLOC_FLAG_LOOP;
395 /* we need to work out who will own an abandoned child
396 if it cannot be freed. In priority order, the first
397 choice is owner of any remaining reference to this
398 pointer, the second choice is our parent, and the
399 final choice is the null context. */
400 void *child = TC_PTR_FROM_CHUNK(tc->child);
401 const void *new_parent = null_context;
402 if (unlikely(tc->child->refs)) {
403 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
404 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
406 if (unlikely(_talloc_free(child) == -1)) {
407 if (new_parent == null_context) {
408 struct talloc_chunk *p = talloc_parent_chunk(ptr);
409 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
411 talloc_steal(new_parent, child);
415 tc->flags |= TALLOC_FLAG_FREE;
417 if (unlikely(tc->flags & TALLOC_FLAG_EXT_ALLOC))
418 tc_external_free(tc, oldparent);
426 move a lump of memory from one talloc context to another return the
427 ptr on success, or NULL if it could not be transferred.
428 passing NULL as ptr will always return NULL with no side effects.
430 void *_talloc_steal(const void *new_ctx, const void *ptr)
432 struct talloc_chunk *tc, *new_tc;
434 if (unlikely(!ptr)) {
438 if (unlikely(new_ctx == NULL)) {
439 new_ctx = null_context;
442 tc = talloc_chunk_from_ptr(ptr);
444 if (unlikely(new_ctx == NULL)) {
446 _TLIST_REMOVE(tc->parent->child, tc);
447 if (tc->parent->child) {
448 tc->parent->child->parent = tc->parent;
451 if (tc->prev) tc->prev->next = tc->next;
452 if (tc->next) tc->next->prev = tc->prev;
455 tc->parent = tc->next = tc->prev = NULL;
456 return discard_const_p(void, ptr);
459 new_tc = talloc_chunk_from_ptr(new_ctx);
461 if (unlikely(tc == new_tc || tc->parent == new_tc)) {
462 return discard_const_p(void, ptr);
466 _TLIST_REMOVE(tc->parent->child, tc);
467 if (tc->parent->child) {
468 tc->parent->child->parent = tc->parent;
471 if (tc->prev) tc->prev->next = tc->next;
472 if (tc->next) tc->next->prev = tc->prev;
476 if (new_tc->child) new_tc->child->parent = NULL;
477 _TLIST_ADD(new_tc->child, tc);
479 return discard_const_p(void, ptr);
485 remove a secondary reference to a pointer. This undo's what
486 talloc_reference() has done. The context and pointer arguments
487 must match those given to a talloc_reference()
489 static inline int talloc_unreference(const void *context, const void *ptr)
491 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
492 struct talloc_reference_handle *h;
494 if (unlikely(context == NULL)) {
495 context = null_context;
498 for (h=tc->refs;h;h=h->next) {
499 struct talloc_chunk *p = talloc_parent_chunk(h);
501 if (context == NULL) break;
502 } else if (TC_PTR_FROM_CHUNK(p) == context) {
510 return _talloc_free(h);
514 remove a specific parent context from a pointer. This is a more
515 controlled varient of talloc_free()
517 int talloc_unlink(const void *context, void *ptr)
519 struct talloc_chunk *tc_p, *new_p;
526 if (context == NULL) {
527 context = null_context;
530 if (talloc_unreference(context, ptr) == 0) {
534 if (context == NULL) {
535 if (talloc_parent_chunk(ptr) != NULL) {
539 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
544 tc_p = talloc_chunk_from_ptr(ptr);
546 if (tc_p->refs == NULL) {
547 return _talloc_free(ptr);
550 new_p = talloc_parent_chunk(tc_p->refs);
552 new_parent = TC_PTR_FROM_CHUNK(new_p);
557 if (talloc_unreference(new_parent, ptr) != 0) {
561 talloc_steal(new_parent, ptr);
567 add a name to an existing pointer - va_list version
569 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
571 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
573 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
574 tc->name = talloc_vasprintf(ptr, fmt, ap);
575 if (likely(tc->name)) {
576 _talloc_set_name_const(tc->name, ".name");
582 add a name to an existing pointer
584 const char *talloc_set_name(const void *ptr, const char *fmt, ...)
589 name = talloc_set_name_v(ptr, fmt, ap);
596 create a named talloc pointer. Any talloc pointer can be named, and
597 talloc_named() operates just like talloc() except that it allows you
600 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
606 ptr = __talloc(context, size);
607 if (unlikely(ptr == NULL)) return NULL;
610 name = talloc_set_name_v(ptr, fmt, ap);
613 if (unlikely(name == NULL)) {
622 return the name of a talloc ptr, or "UNNAMED"
624 const char *talloc_get_name(const void *ptr)
626 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
627 if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
630 if (likely(tc->name)) {
638 check if a pointer has the given name. If it does, return the pointer,
639 otherwise return NULL
641 void *talloc_check_name(const void *ptr, const char *name)
644 if (unlikely(ptr == NULL)) return NULL;
645 pname = talloc_get_name(ptr);
646 if (likely(pname == name || strcmp(pname, name) == 0)) {
647 return discard_const_p(void, ptr);
654 this is for compatibility with older versions of talloc
656 void *talloc_init(const char *fmt, ...)
663 * samba3 expects talloc_report_depth_cb(NULL, ...)
664 * reports all talloc'ed memory, so we need to enable
667 talloc_enable_null_tracking();
669 ptr = __talloc(NULL, 0);
670 if (unlikely(ptr == NULL)) return NULL;
673 name = talloc_set_name_v(ptr, fmt, ap);
676 if (unlikely(name == NULL)) {
685 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
686 should probably not be used in new code. It's in here to keep the talloc
687 code consistent across Samba 3 and 4.
689 void talloc_free_children(void *ptr)
691 struct talloc_chunk *tc;
693 if (unlikely(ptr == NULL)) {
697 tc = talloc_chunk_from_ptr(ptr);
700 /* we need to work out who will own an abandoned child
701 if it cannot be freed. In priority order, the first
702 choice is owner of any remaining reference to this
703 pointer, the second choice is our parent, and the
704 final choice is the null context. */
705 void *child = TC_PTR_FROM_CHUNK(tc->child);
706 const void *new_parent = null_context;
707 if (unlikely(tc->child->refs)) {
708 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
709 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
711 if (unlikely(_talloc_free(child) == -1)) {
712 if (new_parent == null_context) {
713 struct talloc_chunk *p = talloc_parent_chunk(ptr);
714 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
716 talloc_steal(new_parent, child);
722 Allocate a bit of memory as a child of an existing pointer
724 void *_talloc(const void *context, size_t size)
726 return __talloc(context, size);
730 externally callable talloc_set_name_const()
732 void talloc_set_name_const(const void *ptr, const char *name)
734 _talloc_set_name_const(ptr, name);
738 create a named talloc pointer. Any talloc pointer can be named, and
739 talloc_named() operates just like talloc() except that it allows you
742 void *talloc_named_const(const void *context, size_t size, const char *name)
744 return _talloc_named_const(context, size, name);
748 free a talloc pointer. This also frees all child pointers of this
751 return 0 if the memory is actually freed, otherwise -1. The memory
752 will not be freed if the ref_count is > 1 or the destructor (if
753 any) returns non-zero
755 int talloc_free(void *ptr)
757 int saved_errno = errno, ret;
758 ret = _talloc_free(ptr);
767 A talloc version of realloc. The context argument is only used if
770 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
772 struct talloc_chunk *tc;
775 /* size zero is equivalent to free() */
776 if (unlikely(size == 0)) {
781 if (unlikely(size >= MAX_TALLOC_SIZE)) {
785 /* realloc(NULL) is equivalent to malloc() */
787 return _talloc_named_const(context, size, name);
790 tc = talloc_chunk_from_ptr(ptr);
792 /* don't allow realloc on referenced pointers */
793 if (unlikely(tc->refs)) {
797 if (unlikely(tc->flags & TALLOC_FLAG_EXT_ALLOC)) {
798 /* need to get parent before setting free flag. */
799 void *parent = talloc_parent(ptr);
800 tc->flags |= TALLOC_FLAG_FREE;
801 new_ptr = tc_external_realloc(tc, parent, size + TC_HDR_SIZE);
803 /* by resetting magic we catch users of the old memory */
804 tc->flags |= TALLOC_FLAG_FREE;
807 new_ptr = malloc(size + TC_HDR_SIZE);
809 memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
813 new_ptr = realloc(tc, size + TC_HDR_SIZE);
817 if (unlikely(!new_ptr)) {
818 tc->flags &= ~TALLOC_FLAG_FREE;
822 tc = (struct talloc_chunk *)new_ptr;
823 tc->flags &= ~TALLOC_FLAG_FREE;
825 tc->parent->child = tc;
828 tc->child->parent = tc;
839 _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
841 return TC_PTR_FROM_CHUNK(tc);
845 a wrapper around talloc_steal() for situations where you are moving a pointer
846 between two structures, and want the old pointer to be set to NULL
848 void *_talloc_move(const void *new_ctx, const void *_pptr)
850 const void **pptr = discard_const_p(const void *,_pptr);
851 void *ret = _talloc_steal(new_ctx, *pptr);
857 return the total size of a talloc pool (subtree)
859 size_t talloc_total_size(const void *ptr)
862 struct talloc_chunk *c, *tc;
871 tc = talloc_chunk_from_ptr(ptr);
873 if (tc->flags & TALLOC_FLAG_LOOP) {
877 tc->flags |= TALLOC_FLAG_LOOP;
880 for (c=tc->child;c;c=c->next) {
881 total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
884 tc->flags &= ~TALLOC_FLAG_LOOP;
890 return the total number of blocks in a talloc pool (subtree)
892 size_t talloc_total_blocks(const void *ptr)
895 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
897 if (tc->flags & TALLOC_FLAG_LOOP) {
901 tc->flags |= TALLOC_FLAG_LOOP;
904 for (c=tc->child;c;c=c->next) {
905 total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
908 tc->flags &= ~TALLOC_FLAG_LOOP;
914 return the number of external references to a pointer
916 size_t talloc_reference_count(const void *ptr)
918 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
919 struct talloc_reference_handle *h;
922 for (h=tc->refs;h;h=h->next) {
929 report on memory usage by all children of a pointer, giving a full tree view
931 void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
932 void (*callback)(const void *ptr,
933 int depth, int max_depth,
938 struct talloc_chunk *c, *tc;
943 if (ptr == NULL) return;
945 tc = talloc_chunk_from_ptr(ptr);
947 if (tc->flags & TALLOC_FLAG_LOOP) {
951 callback(ptr, depth, max_depth, 0, private_data);
953 if (max_depth >= 0 && depth >= max_depth) {
957 tc->flags |= TALLOC_FLAG_LOOP;
958 for (c=tc->child;c;c=c->next) {
959 if (c->name == TALLOC_MAGIC_REFERENCE) {
960 struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
961 callback(h->ptr, depth + 1, max_depth, 1, private_data);
963 talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
966 tc->flags &= ~TALLOC_FLAG_LOOP;
969 static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
971 const char *name = talloc_get_name(ptr);
972 FILE *f = (FILE *)_f;
975 fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
980 fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n",
981 (max_depth < 0 ? "full " :""), name,
982 (unsigned long)talloc_total_size(ptr),
983 (unsigned long)talloc_total_blocks(ptr));
987 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
990 (unsigned long)talloc_total_size(ptr),
991 (unsigned long)talloc_total_blocks(ptr),
992 (int)talloc_reference_count(ptr), ptr);
995 fprintf(f, "content: ");
996 if (talloc_total_size(ptr)) {
997 int tot = talloc_total_size(ptr);
1000 for (i = 0; i < tot; i++) {
1001 if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
1002 fprintf(f, "%c", ((char *)ptr)[i]);
1004 fprintf(f, "~%02x", ((char *)ptr)[i]);
1013 report on memory usage by all children of a pointer, giving a full tree view
1015 void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
1017 talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
1022 report on memory usage by all children of a pointer, giving a full tree view
1024 void talloc_report_full(const void *ptr, FILE *f)
1026 talloc_report_depth_file(ptr, 0, -1, f);
1030 report on memory usage by all children of a pointer
1032 void talloc_report(const void *ptr, FILE *f)
1034 talloc_report_depth_file(ptr, 0, 1, f);
1038 report on any memory hanging off the null context
1040 static void talloc_report_null(void)
1042 if (talloc_total_size(null_context) != 0) {
1043 talloc_report(null_context, stderr);
1048 report on any memory hanging off the null context
1050 static void talloc_report_null_full(void)
1052 if (talloc_total_size(null_context) != 0) {
1053 talloc_report_full(null_context, stderr);
1058 enable tracking of the NULL context
1060 void talloc_enable_null_tracking(void)
1062 if (null_context == NULL) {
1063 null_context = _talloc_named_const(NULL, 0, "null_context");
1068 disable tracking of the NULL context
1070 void talloc_disable_null_tracking(void)
1072 _talloc_free(null_context);
1073 null_context = NULL;
1077 enable leak reporting on exit
1079 void talloc_enable_leak_report(void)
1081 talloc_enable_null_tracking();
1082 atexit(talloc_report_null);
1086 enable full leak reporting on exit
1088 void talloc_enable_leak_report_full(void)
1090 talloc_enable_null_tracking();
1091 atexit(talloc_report_null_full);
1095 talloc and zero memory.
1097 void *_talloc_zero(const void *ctx, size_t size, const char *name)
1099 void *p = _talloc_named_const(ctx, size, name);
1102 memset(p, '\0', size);
1109 memdup with a talloc.
1111 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
1113 void *newp = _talloc_named_const(t, size, name);
1116 memcpy(newp, p, size);
1123 strdup with a talloc
1125 char *talloc_strdup(const void *t, const char *p)
1131 ret = (char *)talloc_memdup(t, p, strlen(p) + 1);
1133 _talloc_set_name_const(ret, ret);
1139 append to a talloced string
1141 char *talloc_append_string(char *orig, const char *append)
1144 size_t olen = strlen(orig);
1150 alenz = strlen(append) + 1;
1152 ret = talloc_realloc(NULL, orig, char, olen + alenz);
1156 /* append the string with the trailing \0 */
1157 memcpy(&ret[olen], append, alenz);
1159 _talloc_set_name_const(ret, ret);
1165 strndup with a talloc
1167 char *talloc_strndup(const void *t, const char *p, size_t n)
1172 for (len=0; len<n && p[len]; len++) ;
1174 ret = (char *)__talloc(t, len + 1);
1175 if (!ret) { return NULL; }
1176 memcpy(ret, p, len);
1178 _talloc_set_name_const(ret, ret);
1182 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1189 /* this call looks strange, but it makes it work on older solaris boxes */
1191 len = vsnprintf(&c, 1, fmt, ap2);
1197 ret = (char *)__talloc(t, len+1);
1200 vsnprintf(ret, len+1, fmt, ap2);
1202 _talloc_set_name_const(ret, ret);
1210 Perform string formatting, and return a pointer to newly allocated
1211 memory holding the result, inside a memory pool.
1213 char *talloc_asprintf(const void *t, const char *fmt, ...)
1219 ret = talloc_vasprintf(t, fmt, ap);
1226 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1227 * and return @p s, which may have moved. Good for gradually
1228 * accumulating output into a string buffer.
1230 char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1232 struct talloc_chunk *tc;
1238 return talloc_vasprintf(NULL, fmt, ap);
1241 tc = talloc_chunk_from_ptr(s);
1243 s_len = tc->size - 1;
1246 len = vsnprintf(&c, 1, fmt, ap2);
1250 /* Either the vsnprintf failed or the format resulted in
1251 * no characters being formatted. In the former case, we
1252 * ought to return NULL, in the latter we ought to return
1253 * the original string. Most current callers of this
1254 * function expect it to never return NULL.
1259 s = talloc_realloc(NULL, s, char, s_len + len+1);
1260 if (!s) return NULL;
1263 vsnprintf(s+s_len, len+1, fmt, ap2);
1265 _talloc_set_name_const(s, s);
1271 Realloc @p s to append the formatted result of @p fmt and return @p
1272 s, which may have moved. Good for gradually accumulating output
1273 into a string buffer.
1275 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1280 s = talloc_vasprintf_append(s, fmt, ap);
1286 alloc an array, checking for integer overflow in the array size
1288 void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1290 if (count >= MAX_TALLOC_SIZE/el_size) {
1293 return _talloc_named_const(ctx, el_size * count, name);
1297 alloc an zero array, checking for integer overflow in the array size
1299 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1301 if (count >= MAX_TALLOC_SIZE/el_size) {
1304 return _talloc_zero(ctx, el_size * count, name);
1308 realloc an array, checking for integer overflow in the array size
1310 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1312 if (count >= MAX_TALLOC_SIZE/el_size) {
1315 return _talloc_realloc(ctx, ptr, el_size * count, name);
1319 a function version of talloc_realloc(), so it can be passed as a function pointer
1320 to libraries that want a realloc function (a realloc function encapsulates
1321 all the basic capabilities of an allocation library, which is why this is useful)
1323 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1325 return _talloc_realloc(context, ptr, size, NULL);
1329 static int talloc_autofree_destructor(void *ptr)
1331 autofree_context = NULL;
1335 static void talloc_autofree(void)
1337 _talloc_free(autofree_context);
1341 return a context which will be auto-freed on exit
1342 this is useful for reducing the noise in leak reports
1344 void *talloc_autofree_context(void)
1346 if (autofree_context == NULL) {
1347 autofree_context = _talloc_named_const(NULL, 0, "autofree_context");
1348 talloc_set_destructor(autofree_context, talloc_autofree_destructor);
1349 atexit(talloc_autofree);
1351 return autofree_context;
1354 size_t talloc_get_size(const void *context)
1356 struct talloc_chunk *tc;
1358 if (context == NULL)
1361 tc = talloc_chunk_from_ptr(context);
1367 find a parent of this context that has the given name, if any
1369 void *talloc_find_parent_byname(const void *context, const char *name)
1371 struct talloc_chunk *tc;
1373 if (context == NULL) {
1377 tc = talloc_chunk_from_ptr(context);
1379 if (tc->name && strcmp(tc->name, name) == 0) {
1380 return TC_PTR_FROM_CHUNK(tc);
1382 while (tc && tc->prev) tc = tc->prev;
1391 show the parentage of a context
1393 void talloc_show_parents(const void *context, FILE *file)
1395 struct talloc_chunk *tc;
1397 if (context == NULL) {
1398 fprintf(file, "talloc no parents for NULL\n");
1402 tc = talloc_chunk_from_ptr(context);
1403 fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
1405 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
1406 while (tc && tc->prev) tc = tc->prev;
1415 return 1 if ptr is a parent of context
1417 int talloc_is_parent(const void *context, const void *ptr)
1419 struct talloc_chunk *tc;
1421 if (context == NULL) {
1425 tc = talloc_chunk_from_ptr(context);
1427 if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
1428 while (tc && tc->prev) tc = tc->prev;
1436 void talloc_external_enable(void *(*alloc)(void *parent, size_t size),
1437 void (*free)(void *ptr, void *parent),
1438 void *(*realloc)(void *ptr, void *parent, size_t))
1440 tc_external_alloc = alloc;
1441 tc_external_free = free;
1442 tc_external_realloc = realloc;
1445 void talloc_mark_external(void *context)
1447 struct talloc_chunk *tc;
1449 if (unlikely(context == NULL)) {
1450 context = null_context;
1453 tc = talloc_chunk_from_ptr(context);
1454 tc->flags |= TALLOC_FLAG_EXT_ALLOC;