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/
38 #include <sys/types.h>
41 /* use this to force every realloc to change the pointer, to stress test
42 code that might not cope */
43 #define ALWAYS_REALLOC 0
46 #define MAX_TALLOC_SIZE 0x10000000
47 #define TALLOC_MAGIC 0xe814ec70
48 #define TALLOC_FLAG_FREE 0x01
49 #define TALLOC_FLAG_LOOP 0x02
50 #define TALLOC_FLAG_EXT_ALLOC 0x04
51 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
53 /* by default we abort when given a bad pointer (such as when talloc_free() is called
54 on a pointer that came from malloc() */
56 #define TALLOC_ABORT(reason) abort()
59 #ifndef discard_const_p
60 #if defined(INTPTR_MIN)
61 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
63 # define discard_const_p(type, ptr) ((type *)(ptr))
67 /* these macros gain us a few percent of speed on gcc */
68 #if HAVE_BUILTIN_EXPECT
69 /* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
70 as its first argument */
71 #define likely(x) __builtin_expect(!!(x), 1)
72 #define unlikely(x) __builtin_expect(!!(x), 0)
78 /* this null_context is only used if talloc_enable_leak_report() or
79 talloc_enable_leak_report_full() is called, otherwise it remains
82 static void *null_context;
83 static pid_t *autofree_context;
85 static void *(*tc_external_realloc)(const void *parent, void *ptr, 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;
183 static void *init_talloc(struct talloc_chunk *parent,
184 struct talloc_chunk *tc,
185 size_t size, int external)
187 if (unlikely(tc == NULL))
191 tc->flags = TALLOC_MAGIC;
193 tc->flags |= TALLOC_FLAG_EXT_ALLOC;
194 tc->destructor = NULL;
199 if (likely(parent)) {
201 parent->child->parent = NULL;
202 tc->next = parent->child;
211 tc->next = tc->prev = tc->parent = NULL;
214 return TC_PTR_FROM_CHUNK(tc);
218 Allocate a bit of memory as a child of an existing pointer
220 static inline void *__talloc(const void *context, size_t size)
222 struct talloc_chunk *tc;
223 struct talloc_chunk *parent = NULL;
226 if (unlikely(context == NULL)) {
227 context = null_context;
230 if (unlikely(size >= MAX_TALLOC_SIZE)) {
234 if (likely(context)) {
235 parent = talloc_chunk_from_ptr(context);
236 if (unlikely(parent->flags & TALLOC_FLAG_EXT_ALLOC)) {
237 tc = tc_external_realloc(context, NULL,
244 tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size);
246 return init_talloc(parent, tc, size, external);
250 setup a destructor to be called on free of a pointer
251 the destructor should return 0 on success, or -1 on failure.
252 if the destructor fails then the free is failed, and the memory can
253 be continued to be used
255 void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
257 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
258 tc->destructor = destructor;
262 increase the reference count on a piece of memory.
264 int talloc_increase_ref_count(const void *ptr)
266 if (unlikely(!talloc_reference(null_context, ptr))) {
273 helper for talloc_reference()
275 this is referenced by a function pointer and should not be inline
277 static int talloc_reference_destructor(struct talloc_reference_handle *handle)
279 struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
280 _TLIST_REMOVE(ptr_tc->refs, handle);
285 more efficient way to add a name to a pointer - the name must point to a
288 static inline void _talloc_set_name_const(const void *ptr, const char *name)
290 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
295 internal talloc_named_const()
297 static inline void *_talloc_named_const(const void *context, size_t size, const char *name)
301 ptr = __talloc(context, size);
302 if (unlikely(ptr == NULL)) {
306 _talloc_set_name_const(ptr, name);
312 make a secondary reference to a pointer, hanging off the given context.
313 the pointer remains valid until both the original caller and this given
316 the major use for this is when two different structures need to reference the
317 same underlying data, and you want to be able to free the two instances separately,
320 void *_talloc_reference(const void *context, const void *ptr)
322 struct talloc_chunk *tc;
323 struct talloc_reference_handle *handle;
324 if (unlikely(ptr == NULL)) return NULL;
326 tc = talloc_chunk_from_ptr(ptr);
327 handle = (struct talloc_reference_handle *)_talloc_named_const(context,
328 sizeof(struct talloc_reference_handle),
329 TALLOC_MAGIC_REFERENCE);
330 if (unlikely(handle == NULL)) return NULL;
332 /* note that we hang the destructor off the handle, not the
333 main context as that allows the caller to still setup their
334 own destructor on the context if they want to */
335 talloc_set_destructor(handle, talloc_reference_destructor);
336 handle->ptr = discard_const_p(void, ptr);
337 _TLIST_ADD(tc->refs, handle);
343 internal talloc_free call
345 static inline int _talloc_free(void *ptr)
347 struct talloc_chunk *tc;
348 void *oldparent = NULL;
350 if (unlikely(ptr == NULL)) {
354 tc = talloc_chunk_from_ptr(ptr);
356 if (unlikely(tc->refs)) {
358 /* check this is a reference from a child or grantchild
359 * back to it's parent or grantparent
361 * in that case we need to remove the reference and
362 * call another instance of talloc_free() on the current
365 is_child = talloc_is_parent(tc->refs, ptr);
366 _talloc_free(tc->refs);
368 return _talloc_free(ptr);
373 if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) {
374 /* we have a free loop - stop looping */
378 if (unlikely(tc->destructor)) {
379 talloc_destructor_t d = tc->destructor;
380 if (d == (talloc_destructor_t)-1) {
383 tc->destructor = (talloc_destructor_t)-1;
388 tc->destructor = NULL;
391 if (unlikely(tc->flags & TALLOC_FLAG_EXT_ALLOC))
392 oldparent = talloc_parent(ptr);
395 _TLIST_REMOVE(tc->parent->child, tc);
396 if (tc->parent->child) {
397 tc->parent->child->parent = tc->parent;
400 if (tc->prev) tc->prev->next = tc->next;
401 if (tc->next) tc->next->prev = tc->prev;
404 tc->flags |= TALLOC_FLAG_LOOP;
407 /* we need to work out who will own an abandoned child
408 if it cannot be freed. In priority order, the first
409 choice is owner of any remaining reference to this
410 pointer, the second choice is our parent, and the
411 final choice is the null context. */
412 void *child = TC_PTR_FROM_CHUNK(tc->child);
413 const void *new_parent = null_context;
414 if (unlikely(tc->child->refs)) {
415 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
416 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
418 if (unlikely(_talloc_free(child) == -1)) {
419 if (new_parent == null_context) {
420 struct talloc_chunk *p = talloc_parent_chunk(ptr);
421 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
423 talloc_steal(new_parent, child);
427 tc->flags |= TALLOC_FLAG_FREE;
429 if (unlikely(tc->flags & TALLOC_FLAG_EXT_ALLOC))
430 tc_external_realloc(oldparent, tc, 0);
438 move a lump of memory from one talloc context to another return the
439 ptr on success, or NULL if it could not be transferred.
440 passing NULL as ptr will always return NULL with no side effects.
442 void *_talloc_steal(const void *new_ctx, const void *ptr)
444 struct talloc_chunk *tc, *new_tc;
446 if (unlikely(!ptr)) {
450 if (unlikely(new_ctx == NULL)) {
451 new_ctx = null_context;
454 tc = talloc_chunk_from_ptr(ptr);
456 if (unlikely(new_ctx == NULL)) {
458 _TLIST_REMOVE(tc->parent->child, tc);
459 if (tc->parent->child) {
460 tc->parent->child->parent = tc->parent;
463 if (tc->prev) tc->prev->next = tc->next;
464 if (tc->next) tc->next->prev = tc->prev;
467 tc->parent = tc->next = tc->prev = NULL;
468 return discard_const_p(void, ptr);
471 new_tc = talloc_chunk_from_ptr(new_ctx);
473 if (unlikely(tc == new_tc || tc->parent == new_tc)) {
474 return discard_const_p(void, ptr);
478 _TLIST_REMOVE(tc->parent->child, tc);
479 if (tc->parent->child) {
480 tc->parent->child->parent = tc->parent;
483 if (tc->prev) tc->prev->next = tc->next;
484 if (tc->next) tc->next->prev = tc->prev;
488 if (new_tc->child) new_tc->child->parent = NULL;
489 _TLIST_ADD(new_tc->child, tc);
491 return discard_const_p(void, ptr);
497 remove a secondary reference to a pointer. This undo's what
498 talloc_reference() has done. The context and pointer arguments
499 must match those given to a talloc_reference()
501 static inline int talloc_unreference(const void *context, const void *ptr)
503 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
504 struct talloc_reference_handle *h;
506 if (unlikely(context == NULL)) {
507 context = null_context;
510 for (h=tc->refs;h;h=h->next) {
511 struct talloc_chunk *p = talloc_parent_chunk(h);
513 if (context == NULL) break;
514 } else if (TC_PTR_FROM_CHUNK(p) == context) {
522 return _talloc_free(h);
526 remove a specific parent context from a pointer. This is a more
527 controlled varient of talloc_free()
529 int talloc_unlink(const void *context, void *ptr)
531 struct talloc_chunk *tc_p, *new_p;
538 if (context == NULL) {
539 context = null_context;
542 if (talloc_unreference(context, ptr) == 0) {
546 if (context == NULL) {
547 if (talloc_parent_chunk(ptr) != NULL) {
551 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
556 tc_p = talloc_chunk_from_ptr(ptr);
558 if (tc_p->refs == NULL) {
559 return _talloc_free(ptr);
562 new_p = talloc_parent_chunk(tc_p->refs);
564 new_parent = TC_PTR_FROM_CHUNK(new_p);
569 if (talloc_unreference(new_parent, ptr) != 0) {
573 talloc_steal(new_parent, ptr);
579 add a name to an existing pointer - va_list version
581 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
583 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
585 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
586 tc->name = talloc_vasprintf(ptr, fmt, ap);
587 if (likely(tc->name)) {
588 _talloc_set_name_const(tc->name, ".name");
594 add a name to an existing pointer
596 const char *talloc_set_name(const void *ptr, const char *fmt, ...)
601 name = talloc_set_name_v(ptr, fmt, ap);
608 create a named talloc pointer. Any talloc pointer can be named, and
609 talloc_named() operates just like talloc() except that it allows you
612 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
618 ptr = __talloc(context, size);
619 if (unlikely(ptr == NULL)) return NULL;
622 name = talloc_set_name_v(ptr, fmt, ap);
625 if (unlikely(name == NULL)) {
634 return the name of a talloc ptr, or "UNNAMED"
636 const char *talloc_get_name(const void *ptr)
638 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
639 if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
642 if (likely(tc->name)) {
650 check if a pointer has the given name. If it does, return the pointer,
651 otherwise return NULL
653 void *talloc_check_name(const void *ptr, const char *name)
656 if (unlikely(ptr == NULL)) return NULL;
657 pname = talloc_get_name(ptr);
658 if (likely(pname == name || strcmp(pname, name) == 0)) {
659 return discard_const_p(void, ptr);
666 this is for compatibility with older versions of talloc
668 void *talloc_init(const char *fmt, ...)
675 * samba3 expects talloc_report_depth_cb(NULL, ...)
676 * reports all talloc'ed memory, so we need to enable
679 talloc_enable_null_tracking();
681 ptr = __talloc(NULL, 0);
682 if (unlikely(ptr == NULL)) return NULL;
685 name = talloc_set_name_v(ptr, fmt, ap);
688 if (unlikely(name == NULL)) {
697 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
698 should probably not be used in new code. It's in here to keep the talloc
699 code consistent across Samba 3 and 4.
701 void talloc_free_children(void *ptr)
703 struct talloc_chunk *tc;
705 if (unlikely(ptr == NULL)) {
709 tc = talloc_chunk_from_ptr(ptr);
712 /* we need to work out who will own an abandoned child
713 if it cannot be freed. In priority order, the first
714 choice is owner of any remaining reference to this
715 pointer, the second choice is our parent, and the
716 final choice is the null context. */
717 void *child = TC_PTR_FROM_CHUNK(tc->child);
718 const void *new_parent = null_context;
719 if (unlikely(tc->child->refs)) {
720 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
721 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
723 if (unlikely(_talloc_free(child) == -1)) {
724 if (new_parent == null_context) {
725 struct talloc_chunk *p = talloc_parent_chunk(ptr);
726 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
728 talloc_steal(new_parent, child);
734 Allocate a bit of memory as a child of an existing pointer
736 void *_talloc(const void *context, size_t size)
738 return __talloc(context, size);
742 externally callable talloc_set_name_const()
744 void talloc_set_name_const(const void *ptr, const char *name)
746 _talloc_set_name_const(ptr, name);
750 create a named talloc pointer. Any talloc pointer can be named, and
751 talloc_named() operates just like talloc() except that it allows you
754 void *talloc_named_const(const void *context, size_t size, const char *name)
756 return _talloc_named_const(context, size, name);
760 free a talloc pointer. This also frees all child pointers of this
763 return 0 if the memory is actually freed, otherwise -1. The memory
764 will not be freed if the ref_count is > 1 or the destructor (if
765 any) returns non-zero
767 int talloc_free(void *ptr)
769 int saved_errno = errno, ret;
770 ret = _talloc_free(ptr);
779 A talloc version of realloc. The context argument is only used if
782 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
784 struct talloc_chunk *tc;
787 /* size zero is equivalent to free() */
788 if (unlikely(size == 0)) {
793 if (unlikely(size >= MAX_TALLOC_SIZE)) {
797 /* realloc(NULL) is equivalent to malloc() */
799 return _talloc_named_const(context, size, name);
802 tc = talloc_chunk_from_ptr(ptr);
804 /* don't allow realloc on referenced pointers */
805 if (unlikely(tc->refs)) {
809 if (unlikely(tc->flags & TALLOC_FLAG_EXT_ALLOC)) {
810 /* need to get parent before setting free flag. */
811 void *parent = talloc_parent(ptr);
812 tc->flags |= TALLOC_FLAG_FREE;
813 new_ptr = tc_external_realloc(parent, tc, size + TC_HDR_SIZE);
815 /* by resetting magic we catch users of the old memory */
816 tc->flags |= TALLOC_FLAG_FREE;
819 new_ptr = malloc(size + TC_HDR_SIZE);
821 memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
825 new_ptr = realloc(tc, size + TC_HDR_SIZE);
829 if (unlikely(!new_ptr)) {
830 tc->flags &= ~TALLOC_FLAG_FREE;
834 tc = (struct talloc_chunk *)new_ptr;
835 tc->flags &= ~TALLOC_FLAG_FREE;
837 tc->parent->child = tc;
840 tc->child->parent = tc;
851 _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
853 return TC_PTR_FROM_CHUNK(tc);
857 a wrapper around talloc_steal() for situations where you are moving a pointer
858 between two structures, and want the old pointer to be set to NULL
860 void *_talloc_move(const void *new_ctx, const void *_pptr)
862 const void **pptr = discard_const_p(const void *,_pptr);
863 void *ret = _talloc_steal(new_ctx, *pptr);
869 return the total size of a talloc pool (subtree)
871 size_t talloc_total_size(const void *ptr)
874 struct talloc_chunk *c, *tc;
883 tc = talloc_chunk_from_ptr(ptr);
885 if (tc->flags & TALLOC_FLAG_LOOP) {
889 tc->flags |= TALLOC_FLAG_LOOP;
892 for (c=tc->child;c;c=c->next) {
893 total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
896 tc->flags &= ~TALLOC_FLAG_LOOP;
902 return the total number of blocks in a talloc pool (subtree)
904 size_t talloc_total_blocks(const void *ptr)
907 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
909 if (tc->flags & TALLOC_FLAG_LOOP) {
913 tc->flags |= TALLOC_FLAG_LOOP;
916 for (c=tc->child;c;c=c->next) {
917 total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
920 tc->flags &= ~TALLOC_FLAG_LOOP;
926 return the number of external references to a pointer
928 size_t talloc_reference_count(const void *ptr)
930 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
931 struct talloc_reference_handle *h;
934 for (h=tc->refs;h;h=h->next) {
941 report on memory usage by all children of a pointer, giving a full tree view
943 void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
944 void (*callback)(const void *ptr,
945 int depth, int max_depth,
950 struct talloc_chunk *c, *tc;
955 if (ptr == NULL) return;
957 tc = talloc_chunk_from_ptr(ptr);
959 if (tc->flags & TALLOC_FLAG_LOOP) {
963 callback(ptr, depth, max_depth, 0, private_data);
965 if (max_depth >= 0 && depth >= max_depth) {
969 tc->flags |= TALLOC_FLAG_LOOP;
970 for (c=tc->child;c;c=c->next) {
971 if (c->name == TALLOC_MAGIC_REFERENCE) {
972 struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
973 callback(h->ptr, depth + 1, max_depth, 1, private_data);
975 talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
978 tc->flags &= ~TALLOC_FLAG_LOOP;
981 static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
983 const char *name = talloc_get_name(ptr);
984 FILE *f = (FILE *)_f;
987 fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
992 fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n",
993 (max_depth < 0 ? "full " :""), name,
994 (unsigned long)talloc_total_size(ptr),
995 (unsigned long)talloc_total_blocks(ptr));
999 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
1002 (unsigned long)talloc_total_size(ptr),
1003 (unsigned long)talloc_total_blocks(ptr),
1004 (int)talloc_reference_count(ptr), ptr);
1007 fprintf(f, "content: ");
1008 if (talloc_total_size(ptr)) {
1009 int tot = talloc_total_size(ptr);
1012 for (i = 0; i < tot; i++) {
1013 if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
1014 fprintf(f, "%c", ((char *)ptr)[i]);
1016 fprintf(f, "~%02x", ((char *)ptr)[i]);
1025 report on memory usage by all children of a pointer, giving a full tree view
1027 void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
1029 talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
1034 report on memory usage by all children of a pointer, giving a full tree view
1036 void talloc_report_full(const void *ptr, FILE *f)
1038 talloc_report_depth_file(ptr, 0, -1, f);
1042 report on memory usage by all children of a pointer
1044 void talloc_report(const void *ptr, FILE *f)
1046 talloc_report_depth_file(ptr, 0, 1, f);
1050 report on any memory hanging off the null context
1052 static void talloc_report_null(void)
1054 if (talloc_total_size(null_context) != 0) {
1055 talloc_report(null_context, stderr);
1060 report on any memory hanging off the null context
1062 static void talloc_report_null_full(void)
1064 if (talloc_total_size(null_context) != 0) {
1065 talloc_report_full(null_context, stderr);
1070 enable tracking of the NULL context
1072 void talloc_enable_null_tracking(void)
1074 if (null_context == NULL) {
1075 null_context = _talloc_named_const(NULL, 0, "null_context");
1080 disable tracking of the NULL context
1082 void talloc_disable_null_tracking(void)
1084 _talloc_free(null_context);
1085 null_context = NULL;
1089 enable leak reporting on exit
1091 void talloc_enable_leak_report(void)
1093 talloc_enable_null_tracking();
1094 atexit(talloc_report_null);
1098 enable full leak reporting on exit
1100 void talloc_enable_leak_report_full(void)
1102 talloc_enable_null_tracking();
1103 atexit(talloc_report_null_full);
1107 talloc and zero memory.
1109 void *_talloc_zero(const void *ctx, size_t size, const char *name)
1111 void *p = _talloc_named_const(ctx, size, name);
1114 memset(p, '\0', size);
1121 memdup with a talloc.
1123 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
1125 void *newp = _talloc_named_const(t, size, name);
1128 memcpy(newp, p, size);
1135 strdup with a talloc
1137 char *talloc_strdup(const void *t, const char *p)
1143 ret = (char *)talloc_memdup(t, p, strlen(p) + 1);
1145 _talloc_set_name_const(ret, ret);
1151 append to a talloced string
1153 char *talloc_append_string(char *orig, const char *append)
1156 size_t olen = strlen(orig);
1162 alenz = strlen(append) + 1;
1164 ret = talloc_realloc(NULL, orig, char, olen + alenz);
1168 /* append the string with the trailing \0 */
1169 memcpy(&ret[olen], append, alenz);
1171 _talloc_set_name_const(ret, ret);
1177 strndup with a talloc
1179 char *talloc_strndup(const void *t, const char *p, size_t n)
1184 for (len=0; len<n && p[len]; len++) ;
1186 ret = (char *)__talloc(t, len + 1);
1187 if (!ret) { return NULL; }
1188 memcpy(ret, p, len);
1190 _talloc_set_name_const(ret, ret);
1194 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1201 /* this call looks strange, but it makes it work on older solaris boxes */
1203 len = vsnprintf(&c, 1, fmt, ap2);
1209 ret = (char *)__talloc(t, len+1);
1212 vsnprintf(ret, len+1, fmt, ap2);
1214 _talloc_set_name_const(ret, ret);
1222 Perform string formatting, and return a pointer to newly allocated
1223 memory holding the result, inside a memory pool.
1225 char *talloc_asprintf(const void *t, const char *fmt, ...)
1231 ret = talloc_vasprintf(t, fmt, ap);
1238 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1239 * and return @p s, which may have moved. Good for gradually
1240 * accumulating output into a string buffer.
1242 char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1244 struct talloc_chunk *tc;
1250 return talloc_vasprintf(NULL, fmt, ap);
1253 tc = talloc_chunk_from_ptr(s);
1255 s_len = tc->size - 1;
1258 len = vsnprintf(&c, 1, fmt, ap2);
1262 /* Either the vsnprintf failed or the format resulted in
1263 * no characters being formatted. In the former case, we
1264 * ought to return NULL, in the latter we ought to return
1265 * the original string. Most current callers of this
1266 * function expect it to never return NULL.
1271 s = talloc_realloc(NULL, s, char, s_len + len+1);
1272 if (!s) return NULL;
1275 vsnprintf(s+s_len, len+1, fmt, ap2);
1277 _talloc_set_name_const(s, s);
1283 Realloc @p s to append the formatted result of @p fmt and return @p
1284 s, which may have moved. Good for gradually accumulating output
1285 into a string buffer.
1287 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1292 s = talloc_vasprintf_append(s, fmt, ap);
1298 alloc an array, checking for integer overflow in the array size
1300 void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1302 if (count >= MAX_TALLOC_SIZE/el_size) {
1305 return _talloc_named_const(ctx, el_size * count, name);
1309 alloc an zero array, checking for integer overflow in the array size
1311 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1313 if (count >= MAX_TALLOC_SIZE/el_size) {
1316 return _talloc_zero(ctx, el_size * count, name);
1320 realloc an array, checking for integer overflow in the array size
1322 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1324 if (count >= MAX_TALLOC_SIZE/el_size) {
1327 return _talloc_realloc(ctx, ptr, el_size * count, name);
1331 a function version of talloc_realloc(), so it can be passed as a function pointer
1332 to libraries that want a realloc function (a realloc function encapsulates
1333 all the basic capabilities of an allocation library, which is why this is useful)
1335 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1337 return _talloc_realloc(context, ptr, size, NULL);
1341 static int talloc_autofree_destructor(void *ptr)
1343 autofree_context = NULL;
1347 static void talloc_autofree(void)
1349 if (autofree_context && *autofree_context == getpid())
1350 _talloc_free(autofree_context);
1354 return a context which will be auto-freed on exit
1355 this is useful for reducing the noise in leak reports
1357 void *talloc_autofree_context(void)
1359 if (autofree_context == NULL || *autofree_context != getpid()) {
1360 autofree_context = talloc(NULL, pid_t);
1361 *autofree_context = getpid();
1362 talloc_set_name_const(autofree_context, "autofree_context");
1364 talloc_set_destructor(autofree_context, talloc_autofree_destructor);
1365 atexit(talloc_autofree);
1367 return autofree_context;
1370 size_t talloc_get_size(const void *context)
1372 struct talloc_chunk *tc;
1374 if (context == NULL)
1377 tc = talloc_chunk_from_ptr(context);
1383 find a parent of this context that has the given name, if any
1385 void *talloc_find_parent_byname(const void *context, const char *name)
1387 struct talloc_chunk *tc;
1389 if (context == NULL) {
1393 tc = talloc_chunk_from_ptr(context);
1395 if (tc->name && strcmp(tc->name, name) == 0) {
1396 return TC_PTR_FROM_CHUNK(tc);
1398 while (tc && tc->prev) tc = tc->prev;
1407 show the parentage of a context
1409 void talloc_show_parents(const void *context, FILE *file)
1411 struct talloc_chunk *tc;
1413 if (context == NULL) {
1414 fprintf(file, "talloc no parents for NULL\n");
1418 tc = talloc_chunk_from_ptr(context);
1419 fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
1421 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
1422 while (tc && tc->prev) tc = tc->prev;
1431 return 1 if ptr is a parent of context
1433 int talloc_is_parent(const void *context, const void *ptr)
1435 struct talloc_chunk *tc;
1437 if (context == NULL) {
1441 tc = talloc_chunk_from_ptr(context);
1443 if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
1444 while (tc && tc->prev) tc = tc->prev;
1452 void *talloc_add_external(const void *ctx,
1453 void *(*realloc)(const void *, void *, size_t))
1455 struct talloc_chunk *tc, *parent;
1457 if (tc_external_realloc && tc_external_realloc != realloc)
1458 TALLOC_ABORT("talloc_add_external realloc replaced");
1459 tc_external_realloc = realloc;
1461 if (unlikely(ctx == NULL)) {
1465 parent = talloc_chunk_from_ptr(ctx);
1467 tc = tc_external_realloc(ctx, NULL, TC_HDR_SIZE);
1468 return init_talloc(parent, tc, 0, 1);