report the location of the original talloc_free on double free
[Samba.git] / lib / talloc / talloc.c
blob2709741dfcbd01adbe611e77a25383e6cadb6ace
1 /*
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
13 ** under the LGPL
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 3 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, see <http://www.gnu.org/licenses/>.
30 inspired by http://swapped.cc/halloc/
33 #include "replace.h"
34 #include "talloc.h"
36 #ifdef TALLOC_BUILD_VERSION_MAJOR
37 #if (TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR)
38 #error "TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR"
39 #endif
40 #endif
42 #ifdef TALLOC_BUILD_VERSION_MINOR
43 #if (TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR)
44 #error "TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR"
45 #endif
46 #endif
48 /* use this to force every realloc to change the pointer, to stress test
49 code that might not cope */
50 #define ALWAYS_REALLOC 0
53 #define MAX_TALLOC_SIZE 0x10000000
54 #define TALLOC_MAGIC_BASE 0xe814ec70
55 #define TALLOC_MAGIC ( \
56 TALLOC_MAGIC_BASE + \
57 (TALLOC_VERSION_MAJOR << 12) + \
58 (TALLOC_VERSION_MINOR << 4) \
61 #define TALLOC_FLAG_FREE 0x01
62 #define TALLOC_FLAG_LOOP 0x02
63 #define TALLOC_FLAG_POOL 0x04 /* This is a talloc pool */
64 #define TALLOC_FLAG_POOLMEM 0x08 /* This is allocated in a pool */
65 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
67 /* by default we abort when given a bad pointer (such as when talloc_free() is called
68 on a pointer that came from malloc() */
69 #ifndef TALLOC_ABORT
70 #define TALLOC_ABORT(reason) abort()
71 #endif
73 #ifndef discard_const_p
74 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
75 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
76 #else
77 # define discard_const_p(type, ptr) ((type *)(ptr))
78 #endif
79 #endif
81 /* these macros gain us a few percent of speed on gcc */
82 #if (__GNUC__ >= 3)
83 /* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
84 as its first argument */
85 #ifndef likely
86 #define likely(x) __builtin_expect(!!(x), 1)
87 #endif
88 #ifndef unlikely
89 #define unlikely(x) __builtin_expect(!!(x), 0)
90 #endif
91 #else
92 #ifndef likely
93 #define likely(x) (x)
94 #endif
95 #ifndef unlikely
96 #define unlikely(x) (x)
97 #endif
98 #endif
100 /* this null_context is only used if talloc_enable_leak_report() or
101 talloc_enable_leak_report_full() is called, otherwise it remains
102 NULL
104 static void *null_context;
105 static void *autofree_context;
107 struct talloc_reference_handle {
108 struct talloc_reference_handle *next, *prev;
109 void *ptr;
110 const char *location;
113 typedef int (*talloc_destructor_t)(void *);
115 struct talloc_chunk {
116 struct talloc_chunk *next, *prev;
117 struct talloc_chunk *parent, *child;
118 struct talloc_reference_handle *refs;
119 talloc_destructor_t destructor;
120 const char *name;
121 size_t size;
122 unsigned flags;
125 * "pool" has dual use:
127 * For the talloc pool itself (i.e. TALLOC_FLAG_POOL is set), "pool"
128 * marks the end of the currently allocated area.
130 * For members of the pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool"
131 * is a pointer to the struct talloc_chunk of the pool that it was
132 * allocated from. This way children can quickly find the pool to chew
133 * from.
135 void *pool;
138 /* 16 byte alignment seems to keep everyone happy */
139 #define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
140 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
142 int talloc_version_major(void)
144 return TALLOC_VERSION_MAJOR;
147 int talloc_version_minor(void)
149 return TALLOC_VERSION_MINOR;
152 static void (*talloc_log_fn)(const char *message);
154 void talloc_set_log_fn(void (*log_fn)(const char *message))
156 talloc_log_fn = log_fn;
159 static void talloc_log(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
160 static void talloc_log(const char *fmt, ...)
162 va_list ap;
163 char *message;
165 if (!talloc_log_fn) {
166 return;
169 va_start(ap, fmt);
170 message = talloc_vasprintf(NULL, fmt, ap);
171 va_end(ap);
173 talloc_log_fn(message);
174 talloc_free(message);
177 static void talloc_log_stderr(const char *message)
179 fprintf(stderr, "%s", message);
182 void talloc_set_log_stderr(void)
184 talloc_set_log_fn(talloc_log_stderr);
187 static void (*talloc_abort_fn)(const char *reason);
189 void talloc_set_abort_fn(void (*abort_fn)(const char *reason))
191 talloc_abort_fn = abort_fn;
194 static void talloc_abort(const char *reason)
196 talloc_log("%s\n", reason);
198 if (!talloc_abort_fn) {
199 TALLOC_ABORT(reason);
202 talloc_abort_fn(reason);
205 static void talloc_abort_magic(unsigned magic)
207 unsigned striped = magic - TALLOC_MAGIC_BASE;
208 unsigned major = (striped & 0xFFFFF000) >> 12;
209 unsigned minor = (striped & 0x00000FF0) >> 4;
210 talloc_log("Bad talloc magic[0x%08X/%u/%u] expected[0x%08X/%u/%u]\n",
211 magic, major, minor,
212 TALLOC_MAGIC, TALLOC_VERSION_MAJOR, TALLOC_VERSION_MINOR);
213 talloc_abort("Bad talloc magic value - wrong talloc version used/mixed");
216 static void talloc_abort_double_free(void)
218 talloc_abort("Bad talloc magic value - double free");
221 static void talloc_abort_unknown_value(void)
223 talloc_abort("Bad talloc magic value - unknown value");
226 /* panic if we get a bad magic value */
227 static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
229 const char *pp = (const char *)ptr;
230 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
231 if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) {
232 if ((tc->flags & (~0xFFF)) == TALLOC_MAGIC_BASE) {
233 talloc_abort_magic(tc->flags & (~0xF));
234 return NULL;
237 if (tc->flags & TALLOC_FLAG_FREE) {
238 talloc_log("talloc: double free error - first free may be at %s\n", tc->name);
239 talloc_abort_double_free();
240 return NULL;
241 } else {
242 talloc_abort_unknown_value();
243 return NULL;
246 return tc;
249 /* hook into the front of the list */
250 #define _TLIST_ADD(list, p) \
251 do { \
252 if (!(list)) { \
253 (list) = (p); \
254 (p)->next = (p)->prev = NULL; \
255 } else { \
256 (list)->prev = (p); \
257 (p)->next = (list); \
258 (p)->prev = NULL; \
259 (list) = (p); \
261 } while (0)
263 /* remove an element from a list - element doesn't have to be in list. */
264 #define _TLIST_REMOVE(list, p) \
265 do { \
266 if ((p) == (list)) { \
267 (list) = (p)->next; \
268 if (list) (list)->prev = NULL; \
269 } else { \
270 if ((p)->prev) (p)->prev->next = (p)->next; \
271 if ((p)->next) (p)->next->prev = (p)->prev; \
273 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
274 } while (0)
278 return the parent chunk of a pointer
280 static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr)
282 struct talloc_chunk *tc;
284 if (unlikely(ptr == NULL)) {
285 return NULL;
288 tc = talloc_chunk_from_ptr(ptr);
289 while (tc->prev) tc=tc->prev;
291 return tc->parent;
294 void *talloc_parent(const void *ptr)
296 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
297 return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
301 find parents name
303 const char *talloc_parent_name(const void *ptr)
305 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
306 return tc? tc->name : NULL;
310 A pool carries an in-pool object count count in the first 16 bytes.
311 bytes. This is done to support talloc_steal() to a parent outside of the
312 pool. The count includes the pool itself, so a talloc_free() on a pool will
313 only destroy the pool if the count has dropped to zero. A talloc_free() of a
314 pool member will reduce the count, and eventually also call free(3) on the
315 pool memory.
317 The object count is not put into "struct talloc_chunk" because it is only
318 relevant for talloc pools and the alignment to 16 bytes would increase the
319 memory footprint of each talloc chunk by those 16 bytes.
322 #define TALLOC_POOL_HDR_SIZE 16
324 static unsigned int *talloc_pool_objectcount(struct talloc_chunk *tc)
326 return (unsigned int *)((char *)tc + sizeof(struct talloc_chunk));
330 Allocate from a pool
333 static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,
334 size_t size)
336 struct talloc_chunk *pool_ctx = NULL;
337 size_t space_left;
338 struct talloc_chunk *result;
339 size_t chunk_size;
341 if (parent == NULL) {
342 return NULL;
345 if (parent->flags & TALLOC_FLAG_POOL) {
346 pool_ctx = parent;
348 else if (parent->flags & TALLOC_FLAG_POOLMEM) {
349 pool_ctx = (struct talloc_chunk *)parent->pool;
352 if (pool_ctx == NULL) {
353 return NULL;
356 space_left = ((char *)pool_ctx + TC_HDR_SIZE + pool_ctx->size)
357 - ((char *)pool_ctx->pool);
360 * Align size to 16 bytes
362 chunk_size = ((size + 15) & ~15);
364 if (space_left < chunk_size) {
365 return NULL;
368 result = (struct talloc_chunk *)pool_ctx->pool;
370 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
371 VALGRIND_MAKE_MEM_UNDEFINED(result, size);
372 #endif
374 pool_ctx->pool = (void *)((char *)result + chunk_size);
376 result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM;
377 result->pool = pool_ctx;
379 *talloc_pool_objectcount(pool_ctx) += 1;
381 return result;
385 Allocate a bit of memory as a child of an existing pointer
387 static inline void *__talloc(const void *context, size_t size)
389 struct talloc_chunk *tc = NULL;
391 if (unlikely(context == NULL)) {
392 context = null_context;
395 if (unlikely(size >= MAX_TALLOC_SIZE)) {
396 return NULL;
399 if (context != NULL) {
400 tc = talloc_alloc_pool(talloc_chunk_from_ptr(context),
401 TC_HDR_SIZE+size);
404 if (tc == NULL) {
405 tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size);
406 if (unlikely(tc == NULL)) return NULL;
407 tc->flags = TALLOC_MAGIC;
408 tc->pool = NULL;
411 tc->size = size;
412 tc->destructor = NULL;
413 tc->child = NULL;
414 tc->name = NULL;
415 tc->refs = NULL;
417 if (likely(context)) {
418 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
420 if (parent->child) {
421 parent->child->parent = NULL;
422 tc->next = parent->child;
423 tc->next->prev = tc;
424 } else {
425 tc->next = NULL;
427 tc->parent = parent;
428 tc->prev = NULL;
429 parent->child = tc;
430 } else {
431 tc->next = tc->prev = tc->parent = NULL;
434 return TC_PTR_FROM_CHUNK(tc);
438 * Create a talloc pool
441 void *talloc_pool(const void *context, size_t size)
443 void *result = __talloc(context, size + TALLOC_POOL_HDR_SIZE);
444 struct talloc_chunk *tc;
446 if (unlikely(result == NULL)) {
447 return NULL;
450 tc = talloc_chunk_from_ptr(result);
452 tc->flags |= TALLOC_FLAG_POOL;
453 tc->pool = (char *)result + TALLOC_POOL_HDR_SIZE;
455 *talloc_pool_objectcount(tc) = 1;
457 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
458 VALGRIND_MAKE_MEM_NOACCESS(tc->pool, size);
459 #endif
461 return result;
465 setup a destructor to be called on free of a pointer
466 the destructor should return 0 on success, or -1 on failure.
467 if the destructor fails then the free is failed, and the memory can
468 be continued to be used
470 void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
472 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
473 tc->destructor = destructor;
477 increase the reference count on a piece of memory.
479 int talloc_increase_ref_count(const void *ptr)
481 if (unlikely(!talloc_reference(null_context, ptr))) {
482 return -1;
484 return 0;
488 helper for talloc_reference()
490 this is referenced by a function pointer and should not be inline
492 static int talloc_reference_destructor(struct talloc_reference_handle *handle)
494 struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
495 _TLIST_REMOVE(ptr_tc->refs, handle);
496 return 0;
500 more efficient way to add a name to a pointer - the name must point to a
501 true string constant
503 static inline void _talloc_set_name_const(const void *ptr, const char *name)
505 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
506 tc->name = name;
510 internal talloc_named_const()
512 static inline void *_talloc_named_const(const void *context, size_t size, const char *name)
514 void *ptr;
516 ptr = __talloc(context, size);
517 if (unlikely(ptr == NULL)) {
518 return NULL;
521 _talloc_set_name_const(ptr, name);
523 return ptr;
527 make a secondary reference to a pointer, hanging off the given context.
528 the pointer remains valid until both the original caller and this given
529 context are freed.
531 the major use for this is when two different structures need to reference the
532 same underlying data, and you want to be able to free the two instances separately,
533 and in either order
535 void *_talloc_reference_loc(const void *context, const void *ptr, const char *location)
537 struct talloc_chunk *tc;
538 struct talloc_reference_handle *handle;
539 if (unlikely(ptr == NULL)) return NULL;
541 tc = talloc_chunk_from_ptr(ptr);
542 handle = (struct talloc_reference_handle *)_talloc_named_const(context,
543 sizeof(struct talloc_reference_handle),
544 TALLOC_MAGIC_REFERENCE);
545 if (unlikely(handle == NULL)) return NULL;
547 /* note that we hang the destructor off the handle, not the
548 main context as that allows the caller to still setup their
549 own destructor on the context if they want to */
550 talloc_set_destructor(handle, talloc_reference_destructor);
551 handle->ptr = discard_const_p(void, ptr);
552 handle->location = location;
553 _TLIST_ADD(tc->refs, handle);
554 return handle->ptr;
557 static void *_talloc_steal_internal(const void *new_ctx, const void *ptr);
560 internal talloc_free call
562 static inline int _talloc_free_internal(void *ptr, const char *location)
564 struct talloc_chunk *tc;
566 if (unlikely(ptr == NULL)) {
567 return -1;
570 tc = talloc_chunk_from_ptr(ptr);
572 if (unlikely(tc->refs)) {
573 int is_child;
574 /* check this is a reference from a child or grantchild
575 * back to it's parent or grantparent
577 * in that case we need to remove the reference and
578 * call another instance of talloc_free() on the current
579 * pointer.
581 is_child = talloc_is_parent(tc->refs, ptr);
582 _talloc_free_internal(tc->refs, location);
583 if (is_child) {
584 return _talloc_free_internal(ptr, location);
586 return -1;
589 if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) {
590 /* we have a free loop - stop looping */
591 return 0;
594 if (unlikely(tc->destructor)) {
595 talloc_destructor_t d = tc->destructor;
596 if (d == (talloc_destructor_t)-1) {
597 return -1;
599 tc->destructor = (talloc_destructor_t)-1;
600 if (d(ptr) == -1) {
601 tc->destructor = d;
602 return -1;
604 tc->destructor = NULL;
607 if (tc->parent) {
608 _TLIST_REMOVE(tc->parent->child, tc);
609 if (tc->parent->child) {
610 tc->parent->child->parent = tc->parent;
612 } else {
613 if (tc->prev) tc->prev->next = tc->next;
614 if (tc->next) tc->next->prev = tc->prev;
617 tc->flags |= TALLOC_FLAG_LOOP;
619 while (tc->child) {
620 /* we need to work out who will own an abandoned child
621 if it cannot be freed. In priority order, the first
622 choice is owner of any remaining reference to this
623 pointer, the second choice is our parent, and the
624 final choice is the null context. */
625 void *child = TC_PTR_FROM_CHUNK(tc->child);
626 const void *new_parent = null_context;
627 if (unlikely(tc->child->refs)) {
628 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
629 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
631 if (unlikely(_talloc_free_internal(child, location) == -1)) {
632 if (new_parent == null_context) {
633 struct talloc_chunk *p = talloc_parent_chunk(ptr);
634 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
636 _talloc_steal_internal(new_parent, child);
640 tc->flags |= TALLOC_FLAG_FREE;
642 /* we mark the freed memory with where we called the free
643 * from. This means on a double free error we can report where
644 * the first free came from
646 tc->name = location;
648 if (tc->flags & (TALLOC_FLAG_POOL|TALLOC_FLAG_POOLMEM)) {
649 struct talloc_chunk *pool;
650 unsigned int *pool_object_count;
652 pool = (tc->flags & TALLOC_FLAG_POOL)
653 ? tc : (struct talloc_chunk *)tc->pool;
655 pool_object_count = talloc_pool_objectcount(pool);
657 if (*pool_object_count == 0) {
658 talloc_abort("Pool object count zero!");
659 return 0;
662 *pool_object_count -= 1;
664 if (*pool_object_count == 0) {
665 free(pool);
668 else {
669 free(tc);
671 return 0;
675 move a lump of memory from one talloc context to another return the
676 ptr on success, or NULL if it could not be transferred.
677 passing NULL as ptr will always return NULL with no side effects.
679 static void *_talloc_steal_internal(const void *new_ctx, const void *ptr)
681 struct talloc_chunk *tc, *new_tc;
683 if (unlikely(!ptr)) {
684 return NULL;
687 if (unlikely(new_ctx == NULL)) {
688 new_ctx = null_context;
691 tc = talloc_chunk_from_ptr(ptr);
693 if (unlikely(new_ctx == NULL)) {
694 if (tc->parent) {
695 _TLIST_REMOVE(tc->parent->child, tc);
696 if (tc->parent->child) {
697 tc->parent->child->parent = tc->parent;
699 } else {
700 if (tc->prev) tc->prev->next = tc->next;
701 if (tc->next) tc->next->prev = tc->prev;
704 tc->parent = tc->next = tc->prev = NULL;
705 return discard_const_p(void, ptr);
708 new_tc = talloc_chunk_from_ptr(new_ctx);
710 if (unlikely(tc == new_tc || tc->parent == new_tc)) {
711 return discard_const_p(void, ptr);
714 if (tc->parent) {
715 _TLIST_REMOVE(tc->parent->child, tc);
716 if (tc->parent->child) {
717 tc->parent->child->parent = tc->parent;
719 } else {
720 if (tc->prev) tc->prev->next = tc->next;
721 if (tc->next) tc->next->prev = tc->prev;
724 tc->parent = new_tc;
725 if (new_tc->child) new_tc->child->parent = NULL;
726 _TLIST_ADD(new_tc->child, tc);
728 return discard_const_p(void, ptr);
732 move a lump of memory from one talloc context to another return the
733 ptr on success, or NULL if it could not be transferred.
734 passing NULL as ptr will always return NULL with no side effects.
736 void *_talloc_steal_loc(const void *new_ctx, const void *ptr, const char *location)
738 struct talloc_chunk *tc;
740 if (unlikely(ptr == NULL)) {
741 return NULL;
744 tc = talloc_chunk_from_ptr(ptr);
746 if (unlikely(tc->refs != NULL) && talloc_parent(ptr) != new_ctx) {
747 struct talloc_reference_handle *h;
749 talloc_log("WARNING: talloc_steal with references at %s\n",
750 location);
752 for (h=tc->refs; h; h=h->next) {
753 talloc_log("\treference at %s\n",
754 h->location);
758 return _talloc_steal_internal(new_ctx, ptr);
762 this is like a talloc_steal(), but you must supply the old
763 parent. This resolves the ambiguity in a talloc_steal() which is
764 called on a context that has more than one parent (via references)
766 The old parent can be either a reference or a parent
768 void *talloc_reparent(const void *old_parent, const void *new_parent, const void *ptr)
770 struct talloc_chunk *tc;
771 struct talloc_reference_handle *h;
773 if (unlikely(ptr == NULL)) {
774 return NULL;
777 if (old_parent == talloc_parent(ptr)) {
778 return _talloc_steal_internal(new_parent, ptr);
781 tc = talloc_chunk_from_ptr(ptr);
782 for (h=tc->refs;h;h=h->next) {
783 if (talloc_parent(h) == old_parent) {
784 if (_talloc_steal_internal(new_parent, h) != h) {
785 return NULL;
787 return discard_const_p(void, ptr);
791 /* it wasn't a parent */
792 return NULL;
796 remove a secondary reference to a pointer. This undo's what
797 talloc_reference() has done. The context and pointer arguments
798 must match those given to a talloc_reference()
800 static inline int talloc_unreference(const void *context, const void *ptr)
802 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
803 struct talloc_reference_handle *h;
805 if (unlikely(context == NULL)) {
806 context = null_context;
809 for (h=tc->refs;h;h=h->next) {
810 struct talloc_chunk *p = talloc_parent_chunk(h);
811 if (p == NULL) {
812 if (context == NULL) break;
813 } else if (TC_PTR_FROM_CHUNK(p) == context) {
814 break;
817 if (h == NULL) {
818 return -1;
821 return _talloc_free_internal(h, __location__);
825 remove a specific parent context from a pointer. This is a more
826 controlled varient of talloc_free()
828 int talloc_unlink(const void *context, void *ptr)
830 struct talloc_chunk *tc_p, *new_p;
831 void *new_parent;
833 if (ptr == NULL) {
834 return -1;
837 if (context == NULL) {
838 context = null_context;
841 if (talloc_unreference(context, ptr) == 0) {
842 return 0;
845 if (context == NULL) {
846 if (talloc_parent_chunk(ptr) != NULL) {
847 return -1;
849 } else {
850 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
851 return -1;
855 tc_p = talloc_chunk_from_ptr(ptr);
857 if (tc_p->refs == NULL) {
858 return _talloc_free_internal(ptr, __location__);
861 new_p = talloc_parent_chunk(tc_p->refs);
862 if (new_p) {
863 new_parent = TC_PTR_FROM_CHUNK(new_p);
864 } else {
865 new_parent = NULL;
868 if (talloc_unreference(new_parent, ptr) != 0) {
869 return -1;
872 _talloc_steal_internal(new_parent, ptr);
874 return 0;
878 add a name to an existing pointer - va_list version
880 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
882 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
884 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
885 tc->name = talloc_vasprintf(ptr, fmt, ap);
886 if (likely(tc->name)) {
887 _talloc_set_name_const(tc->name, ".name");
889 return tc->name;
893 add a name to an existing pointer
895 const char *talloc_set_name(const void *ptr, const char *fmt, ...)
897 const char *name;
898 va_list ap;
899 va_start(ap, fmt);
900 name = talloc_set_name_v(ptr, fmt, ap);
901 va_end(ap);
902 return name;
907 create a named talloc pointer. Any talloc pointer can be named, and
908 talloc_named() operates just like talloc() except that it allows you
909 to name the pointer.
911 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
913 va_list ap;
914 void *ptr;
915 const char *name;
917 ptr = __talloc(context, size);
918 if (unlikely(ptr == NULL)) return NULL;
920 va_start(ap, fmt);
921 name = talloc_set_name_v(ptr, fmt, ap);
922 va_end(ap);
924 if (unlikely(name == NULL)) {
925 _talloc_free_internal(ptr, __location__);
926 return NULL;
929 return ptr;
933 return the name of a talloc ptr, or "UNNAMED"
935 const char *talloc_get_name(const void *ptr)
937 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
938 if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
939 return ".reference";
941 if (likely(tc->name)) {
942 return tc->name;
944 return "UNNAMED";
949 check if a pointer has the given name. If it does, return the pointer,
950 otherwise return NULL
952 void *talloc_check_name(const void *ptr, const char *name)
954 const char *pname;
955 if (unlikely(ptr == NULL)) return NULL;
956 pname = talloc_get_name(ptr);
957 if (likely(pname == name || strcmp(pname, name) == 0)) {
958 return discard_const_p(void, ptr);
960 return NULL;
963 static void talloc_abort_type_missmatch(const char *location,
964 const char *name,
965 const char *expected)
967 const char *reason;
969 reason = talloc_asprintf(NULL,
970 "%s: Type mismatch: name[%s] expected[%s]",
971 location,
972 name?name:"NULL",
973 expected);
974 if (!reason) {
975 reason = "Type mismatch";
978 talloc_abort(reason);
981 void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location)
983 const char *pname;
985 if (unlikely(ptr == NULL)) {
986 talloc_abort_type_missmatch(location, NULL, name);
987 return NULL;
990 pname = talloc_get_name(ptr);
991 if (likely(pname == name || strcmp(pname, name) == 0)) {
992 return discard_const_p(void, ptr);
995 talloc_abort_type_missmatch(location, pname, name);
996 return NULL;
1000 this is for compatibility with older versions of talloc
1002 void *talloc_init(const char *fmt, ...)
1004 va_list ap;
1005 void *ptr;
1006 const char *name;
1009 * samba3 expects talloc_report_depth_cb(NULL, ...)
1010 * reports all talloc'ed memory, so we need to enable
1011 * null_tracking
1013 talloc_enable_null_tracking();
1015 ptr = __talloc(NULL, 0);
1016 if (unlikely(ptr == NULL)) return NULL;
1018 va_start(ap, fmt);
1019 name = talloc_set_name_v(ptr, fmt, ap);
1020 va_end(ap);
1022 if (unlikely(name == NULL)) {
1023 _talloc_free_internal(ptr, __location__);
1024 return NULL;
1027 return ptr;
1031 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
1032 should probably not be used in new code. It's in here to keep the talloc
1033 code consistent across Samba 3 and 4.
1035 void talloc_free_children(void *ptr)
1037 struct talloc_chunk *tc;
1039 if (unlikely(ptr == NULL)) {
1040 return;
1043 tc = talloc_chunk_from_ptr(ptr);
1045 while (tc->child) {
1046 /* we need to work out who will own an abandoned child
1047 if it cannot be freed. In priority order, the first
1048 choice is owner of any remaining reference to this
1049 pointer, the second choice is our parent, and the
1050 final choice is the null context. */
1051 void *child = TC_PTR_FROM_CHUNK(tc->child);
1052 const void *new_parent = null_context;
1053 if (unlikely(tc->child->refs)) {
1054 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
1055 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
1057 if (unlikely(talloc_free(child) == -1)) {
1058 if (new_parent == null_context) {
1059 struct talloc_chunk *p = talloc_parent_chunk(ptr);
1060 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
1062 _talloc_steal_internal(new_parent, child);
1066 if ((tc->flags & TALLOC_FLAG_POOL)
1067 && (*talloc_pool_objectcount(tc) == 1)) {
1068 tc->pool = ((char *)tc + TC_HDR_SIZE + TALLOC_POOL_HDR_SIZE);
1069 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
1070 VALGRIND_MAKE_MEM_NOACCESS(
1071 tc->pool, tc->size - TALLOC_POOL_HDR_SIZE);
1072 #endif
1077 Allocate a bit of memory as a child of an existing pointer
1079 void *_talloc(const void *context, size_t size)
1081 return __talloc(context, size);
1085 externally callable talloc_set_name_const()
1087 void talloc_set_name_const(const void *ptr, const char *name)
1089 _talloc_set_name_const(ptr, name);
1093 create a named talloc pointer. Any talloc pointer can be named, and
1094 talloc_named() operates just like talloc() except that it allows you
1095 to name the pointer.
1097 void *talloc_named_const(const void *context, size_t size, const char *name)
1099 return _talloc_named_const(context, size, name);
1103 free a talloc pointer. This also frees all child pointers of this
1104 pointer recursively
1106 return 0 if the memory is actually freed, otherwise -1. The memory
1107 will not be freed if the ref_count is > 1 or the destructor (if
1108 any) returns non-zero
1110 int _talloc_free(void *ptr, const char *location)
1112 struct talloc_chunk *tc;
1114 if (unlikely(ptr == NULL)) {
1115 return -1;
1118 tc = talloc_chunk_from_ptr(ptr);
1120 if (unlikely(tc->refs != NULL)) {
1121 struct talloc_reference_handle *h;
1123 talloc_log("ERROR: talloc_free with references at %s\n",
1124 location);
1126 for (h=tc->refs; h; h=h->next) {
1127 talloc_log("\treference at %s\n",
1128 h->location);
1130 return -1;
1133 return _talloc_free_internal(ptr, location);
1139 A talloc version of realloc. The context argument is only used if
1140 ptr is NULL
1142 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
1144 struct talloc_chunk *tc;
1145 void *new_ptr;
1146 bool malloced = false;
1148 /* size zero is equivalent to free() */
1149 if (unlikely(size == 0)) {
1150 talloc_unlink(context, ptr);
1151 return NULL;
1154 if (unlikely(size >= MAX_TALLOC_SIZE)) {
1155 return NULL;
1158 /* realloc(NULL) is equivalent to malloc() */
1159 if (ptr == NULL) {
1160 return _talloc_named_const(context, size, name);
1163 tc = talloc_chunk_from_ptr(ptr);
1165 /* don't allow realloc on referenced pointers */
1166 if (unlikely(tc->refs)) {
1167 return NULL;
1170 /* don't let anybody try to realloc a talloc_pool */
1171 if (unlikely(tc->flags & TALLOC_FLAG_POOL)) {
1172 return NULL;
1175 /* don't shrink if we have less than 1k to gain */
1176 if ((size < tc->size) && ((tc->size - size) < 1024)) {
1177 tc->size = size;
1178 return ptr;
1181 /* by resetting magic we catch users of the old memory */
1182 tc->flags |= TALLOC_FLAG_FREE;
1184 #if ALWAYS_REALLOC
1185 new_ptr = malloc(size + TC_HDR_SIZE);
1186 if (new_ptr) {
1187 memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
1188 free(tc);
1190 #else
1191 if (tc->flags & TALLOC_FLAG_POOLMEM) {
1193 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE);
1194 *talloc_pool_objectcount((struct talloc_chunk *)
1195 (tc->pool)) -= 1;
1197 if (new_ptr == NULL) {
1198 new_ptr = malloc(TC_HDR_SIZE+size);
1199 malloced = true;
1202 if (new_ptr) {
1203 memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
1206 else {
1207 new_ptr = realloc(tc, size + TC_HDR_SIZE);
1209 #endif
1210 if (unlikely(!new_ptr)) {
1211 tc->flags &= ~TALLOC_FLAG_FREE;
1212 return NULL;
1215 tc = (struct talloc_chunk *)new_ptr;
1216 tc->flags &= ~TALLOC_FLAG_FREE;
1217 if (malloced) {
1218 tc->flags &= ~TALLOC_FLAG_POOLMEM;
1220 if (tc->parent) {
1221 tc->parent->child = tc;
1223 if (tc->child) {
1224 tc->child->parent = tc;
1227 if (tc->prev) {
1228 tc->prev->next = tc;
1230 if (tc->next) {
1231 tc->next->prev = tc;
1234 tc->size = size;
1235 _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
1237 return TC_PTR_FROM_CHUNK(tc);
1241 a wrapper around talloc_steal() for situations where you are moving a pointer
1242 between two structures, and want the old pointer to be set to NULL
1244 void *_talloc_move(const void *new_ctx, const void *_pptr)
1246 const void **pptr = discard_const_p(const void *,_pptr);
1247 void *ret = talloc_steal(new_ctx, discard_const_p(void, *pptr));
1248 (*pptr) = NULL;
1249 return ret;
1253 return the total size of a talloc pool (subtree)
1255 size_t talloc_total_size(const void *ptr)
1257 size_t total = 0;
1258 struct talloc_chunk *c, *tc;
1260 if (ptr == NULL) {
1261 ptr = null_context;
1263 if (ptr == NULL) {
1264 return 0;
1267 tc = talloc_chunk_from_ptr(ptr);
1269 if (tc->flags & TALLOC_FLAG_LOOP) {
1270 return 0;
1273 tc->flags |= TALLOC_FLAG_LOOP;
1275 if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) {
1276 total = tc->size;
1278 for (c=tc->child;c;c=c->next) {
1279 total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
1282 tc->flags &= ~TALLOC_FLAG_LOOP;
1284 return total;
1288 return the total number of blocks in a talloc pool (subtree)
1290 size_t talloc_total_blocks(const void *ptr)
1292 size_t total = 0;
1293 struct talloc_chunk *c, *tc;
1295 if (ptr == NULL) {
1296 ptr = null_context;
1298 if (ptr == NULL) {
1299 return 0;
1302 tc = talloc_chunk_from_ptr(ptr);
1304 if (tc->flags & TALLOC_FLAG_LOOP) {
1305 return 0;
1308 tc->flags |= TALLOC_FLAG_LOOP;
1310 total++;
1311 for (c=tc->child;c;c=c->next) {
1312 total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
1315 tc->flags &= ~TALLOC_FLAG_LOOP;
1317 return total;
1321 return the number of external references to a pointer
1323 size_t talloc_reference_count(const void *ptr)
1325 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1326 struct talloc_reference_handle *h;
1327 size_t ret = 0;
1329 for (h=tc->refs;h;h=h->next) {
1330 ret++;
1332 return ret;
1336 report on memory usage by all children of a pointer, giving a full tree view
1338 void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
1339 void (*callback)(const void *ptr,
1340 int depth, int max_depth,
1341 int is_ref,
1342 void *private_data),
1343 void *private_data)
1345 struct talloc_chunk *c, *tc;
1347 if (ptr == NULL) {
1348 ptr = null_context;
1350 if (ptr == NULL) return;
1352 tc = talloc_chunk_from_ptr(ptr);
1354 if (tc->flags & TALLOC_FLAG_LOOP) {
1355 return;
1358 callback(ptr, depth, max_depth, 0, private_data);
1360 if (max_depth >= 0 && depth >= max_depth) {
1361 return;
1364 tc->flags |= TALLOC_FLAG_LOOP;
1365 for (c=tc->child;c;c=c->next) {
1366 if (c->name == TALLOC_MAGIC_REFERENCE) {
1367 struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
1368 callback(h->ptr, depth + 1, max_depth, 1, private_data);
1369 } else {
1370 talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
1373 tc->flags &= ~TALLOC_FLAG_LOOP;
1376 static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
1378 const char *name = talloc_get_name(ptr);
1379 FILE *f = (FILE *)_f;
1381 if (is_ref) {
1382 fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
1383 return;
1386 if (depth == 0) {
1387 fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n",
1388 (max_depth < 0 ? "full " :""), name,
1389 (unsigned long)talloc_total_size(ptr),
1390 (unsigned long)talloc_total_blocks(ptr));
1391 return;
1394 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
1395 depth*4, "",
1396 name,
1397 (unsigned long)talloc_total_size(ptr),
1398 (unsigned long)talloc_total_blocks(ptr),
1399 (int)talloc_reference_count(ptr), ptr);
1401 #if 0
1402 fprintf(f, "content: ");
1403 if (talloc_total_size(ptr)) {
1404 int tot = talloc_total_size(ptr);
1405 int i;
1407 for (i = 0; i < tot; i++) {
1408 if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
1409 fprintf(f, "%c", ((char *)ptr)[i]);
1410 } else {
1411 fprintf(f, "~%02x", ((char *)ptr)[i]);
1415 fprintf(f, "\n");
1416 #endif
1420 report on memory usage by all children of a pointer, giving a full tree view
1422 void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
1424 talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
1425 fflush(f);
1429 report on memory usage by all children of a pointer, giving a full tree view
1431 void talloc_report_full(const void *ptr, FILE *f)
1433 talloc_report_depth_file(ptr, 0, -1, f);
1437 report on memory usage by all children of a pointer
1439 void talloc_report(const void *ptr, FILE *f)
1441 talloc_report_depth_file(ptr, 0, 1, f);
1445 report on any memory hanging off the null context
1447 static void talloc_report_null(void)
1449 if (talloc_total_size(null_context) != 0) {
1450 talloc_report(null_context, stderr);
1455 report on any memory hanging off the null context
1457 static void talloc_report_null_full(void)
1459 if (talloc_total_size(null_context) != 0) {
1460 talloc_report_full(null_context, stderr);
1465 enable tracking of the NULL context
1467 void talloc_enable_null_tracking(void)
1469 if (null_context == NULL) {
1470 null_context = _talloc_named_const(NULL, 0, "null_context");
1475 disable tracking of the NULL context
1477 void talloc_disable_null_tracking(void)
1479 talloc_free(null_context);
1480 null_context = NULL;
1484 enable leak reporting on exit
1486 void talloc_enable_leak_report(void)
1488 talloc_enable_null_tracking();
1489 atexit(talloc_report_null);
1493 enable full leak reporting on exit
1495 void talloc_enable_leak_report_full(void)
1497 talloc_enable_null_tracking();
1498 atexit(talloc_report_null_full);
1502 talloc and zero memory.
1504 void *_talloc_zero(const void *ctx, size_t size, const char *name)
1506 void *p = _talloc_named_const(ctx, size, name);
1508 if (p) {
1509 memset(p, '\0', size);
1512 return p;
1516 memdup with a talloc.
1518 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
1520 void *newp = _talloc_named_const(t, size, name);
1522 if (likely(newp)) {
1523 memcpy(newp, p, size);
1526 return newp;
1529 static inline char *__talloc_strlendup(const void *t, const char *p, size_t len)
1531 char *ret;
1533 ret = (char *)__talloc(t, len + 1);
1534 if (unlikely(!ret)) return NULL;
1536 memcpy(ret, p, len);
1537 ret[len] = 0;
1539 _talloc_set_name_const(ret, ret);
1540 return ret;
1544 strdup with a talloc
1546 char *talloc_strdup(const void *t, const char *p)
1548 if (unlikely(!p)) return NULL;
1549 return __talloc_strlendup(t, p, strlen(p));
1553 strndup with a talloc
1555 char *talloc_strndup(const void *t, const char *p, size_t n)
1557 if (unlikely(!p)) return NULL;
1558 return __talloc_strlendup(t, p, strnlen(p, n));
1561 static inline char *__talloc_strlendup_append(char *s, size_t slen,
1562 const char *a, size_t alen)
1564 char *ret;
1566 ret = talloc_realloc(NULL, s, char, slen + alen + 1);
1567 if (unlikely(!ret)) return NULL;
1569 /* append the string and the trailing \0 */
1570 memcpy(&ret[slen], a, alen);
1571 ret[slen+alen] = 0;
1573 _talloc_set_name_const(ret, ret);
1574 return ret;
1578 * Appends at the end of the string.
1580 char *talloc_strdup_append(char *s, const char *a)
1582 if (unlikely(!s)) {
1583 return talloc_strdup(NULL, a);
1586 if (unlikely(!a)) {
1587 return s;
1590 return __talloc_strlendup_append(s, strlen(s), a, strlen(a));
1594 * Appends at the end of the talloc'ed buffer,
1595 * not the end of the string.
1597 char *talloc_strdup_append_buffer(char *s, const char *a)
1599 size_t slen;
1601 if (unlikely(!s)) {
1602 return talloc_strdup(NULL, a);
1605 if (unlikely(!a)) {
1606 return s;
1609 slen = talloc_get_size(s);
1610 if (likely(slen > 0)) {
1611 slen--;
1614 return __talloc_strlendup_append(s, slen, a, strlen(a));
1618 * Appends at the end of the string.
1620 char *talloc_strndup_append(char *s, const char *a, size_t n)
1622 if (unlikely(!s)) {
1623 return talloc_strdup(NULL, a);
1626 if (unlikely(!a)) {
1627 return s;
1630 return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n));
1634 * Appends at the end of the talloc'ed buffer,
1635 * not the end of the string.
1637 char *talloc_strndup_append_buffer(char *s, const char *a, size_t n)
1639 size_t slen;
1641 if (unlikely(!s)) {
1642 return talloc_strdup(NULL, a);
1645 if (unlikely(!a)) {
1646 return s;
1649 slen = talloc_get_size(s);
1650 if (likely(slen > 0)) {
1651 slen--;
1654 return __talloc_strlendup_append(s, slen, a, strnlen(a, n));
1657 #ifndef HAVE_VA_COPY
1658 #ifdef HAVE___VA_COPY
1659 #define va_copy(dest, src) __va_copy(dest, src)
1660 #else
1661 #define va_copy(dest, src) (dest) = (src)
1662 #endif
1663 #endif
1665 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1667 int len;
1668 char *ret;
1669 va_list ap2;
1670 char c;
1672 /* this call looks strange, but it makes it work on older solaris boxes */
1673 va_copy(ap2, ap);
1674 len = vsnprintf(&c, 1, fmt, ap2);
1675 va_end(ap2);
1676 if (unlikely(len < 0)) {
1677 return NULL;
1680 ret = (char *)__talloc(t, len+1);
1681 if (unlikely(!ret)) return NULL;
1683 va_copy(ap2, ap);
1684 vsnprintf(ret, len+1, fmt, ap2);
1685 va_end(ap2);
1687 _talloc_set_name_const(ret, ret);
1688 return ret;
1693 Perform string formatting, and return a pointer to newly allocated
1694 memory holding the result, inside a memory pool.
1696 char *talloc_asprintf(const void *t, const char *fmt, ...)
1698 va_list ap;
1699 char *ret;
1701 va_start(ap, fmt);
1702 ret = talloc_vasprintf(t, fmt, ap);
1703 va_end(ap);
1704 return ret;
1707 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
1708 const char *fmt, va_list ap)
1709 PRINTF_ATTRIBUTE(3,0);
1711 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
1712 const char *fmt, va_list ap)
1714 ssize_t alen;
1715 va_list ap2;
1716 char c;
1718 va_copy(ap2, ap);
1719 alen = vsnprintf(&c, 1, fmt, ap2);
1720 va_end(ap2);
1722 if (alen <= 0) {
1723 /* Either the vsnprintf failed or the format resulted in
1724 * no characters being formatted. In the former case, we
1725 * ought to return NULL, in the latter we ought to return
1726 * the original string. Most current callers of this
1727 * function expect it to never return NULL.
1729 return s;
1732 s = talloc_realloc(NULL, s, char, slen + alen + 1);
1733 if (!s) return NULL;
1735 va_copy(ap2, ap);
1736 vsnprintf(s + slen, alen + 1, fmt, ap2);
1737 va_end(ap2);
1739 _talloc_set_name_const(s, s);
1740 return s;
1744 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1745 * and return @p s, which may have moved. Good for gradually
1746 * accumulating output into a string buffer. Appends at the end
1747 * of the string.
1749 char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1751 if (unlikely(!s)) {
1752 return talloc_vasprintf(NULL, fmt, ap);
1755 return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap);
1759 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1760 * and return @p s, which may have moved. Always appends at the
1761 * end of the talloc'ed buffer, not the end of the string.
1763 char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap)
1765 size_t slen;
1767 if (unlikely(!s)) {
1768 return talloc_vasprintf(NULL, fmt, ap);
1771 slen = talloc_get_size(s);
1772 if (likely(slen > 0)) {
1773 slen--;
1776 return __talloc_vaslenprintf_append(s, slen, fmt, ap);
1780 Realloc @p s to append the formatted result of @p fmt and return @p
1781 s, which may have moved. Good for gradually accumulating output
1782 into a string buffer.
1784 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1786 va_list ap;
1788 va_start(ap, fmt);
1789 s = talloc_vasprintf_append(s, fmt, ap);
1790 va_end(ap);
1791 return s;
1795 Realloc @p s to append the formatted result of @p fmt and return @p
1796 s, which may have moved. Good for gradually accumulating output
1797 into a buffer.
1799 char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...)
1801 va_list ap;
1803 va_start(ap, fmt);
1804 s = talloc_vasprintf_append_buffer(s, fmt, ap);
1805 va_end(ap);
1806 return s;
1810 alloc an array, checking for integer overflow in the array size
1812 void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1814 if (count >= MAX_TALLOC_SIZE/el_size) {
1815 return NULL;
1817 return _talloc_named_const(ctx, el_size * count, name);
1821 alloc an zero array, checking for integer overflow in the array size
1823 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1825 if (count >= MAX_TALLOC_SIZE/el_size) {
1826 return NULL;
1828 return _talloc_zero(ctx, el_size * count, name);
1832 realloc an array, checking for integer overflow in the array size
1834 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1836 if (count >= MAX_TALLOC_SIZE/el_size) {
1837 return NULL;
1839 return _talloc_realloc(ctx, ptr, el_size * count, name);
1843 a function version of talloc_realloc(), so it can be passed as a function pointer
1844 to libraries that want a realloc function (a realloc function encapsulates
1845 all the basic capabilities of an allocation library, which is why this is useful)
1847 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1849 return _talloc_realloc(context, ptr, size, NULL);
1853 static int talloc_autofree_destructor(void *ptr)
1855 autofree_context = NULL;
1856 return 0;
1859 static void talloc_autofree(void)
1861 talloc_free(autofree_context);
1865 return a context which will be auto-freed on exit
1866 this is useful for reducing the noise in leak reports
1868 void *talloc_autofree_context(void)
1870 if (autofree_context == NULL) {
1871 autofree_context = _talloc_named_const(NULL, 0, "autofree_context");
1872 talloc_set_destructor(autofree_context, talloc_autofree_destructor);
1873 atexit(talloc_autofree);
1875 return autofree_context;
1878 size_t talloc_get_size(const void *context)
1880 struct talloc_chunk *tc;
1882 if (context == NULL) {
1883 context = null_context;
1885 if (context == NULL) {
1886 return 0;
1889 tc = talloc_chunk_from_ptr(context);
1891 return tc->size;
1895 find a parent of this context that has the given name, if any
1897 void *talloc_find_parent_byname(const void *context, const char *name)
1899 struct talloc_chunk *tc;
1901 if (context == NULL) {
1902 return NULL;
1905 tc = talloc_chunk_from_ptr(context);
1906 while (tc) {
1907 if (tc->name && strcmp(tc->name, name) == 0) {
1908 return TC_PTR_FROM_CHUNK(tc);
1910 while (tc && tc->prev) tc = tc->prev;
1911 if (tc) {
1912 tc = tc->parent;
1915 return NULL;
1919 show the parentage of a context
1921 void talloc_show_parents(const void *context, FILE *file)
1923 struct talloc_chunk *tc;
1925 if (context == NULL) {
1926 fprintf(file, "talloc no parents for NULL\n");
1927 return;
1930 tc = talloc_chunk_from_ptr(context);
1931 fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
1932 while (tc) {
1933 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
1934 while (tc && tc->prev) tc = tc->prev;
1935 if (tc) {
1936 tc = tc->parent;
1939 fflush(file);
1943 return 1 if ptr is a parent of context
1945 int talloc_is_parent(const void *context, const void *ptr)
1947 struct talloc_chunk *tc;
1949 if (context == NULL) {
1950 return 0;
1953 tc = talloc_chunk_from_ptr(context);
1954 while (tc) {
1955 if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
1956 while (tc && tc->prev) tc = tc->prev;
1957 if (tc) {
1958 tc = tc->parent;
1961 return 0;