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 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/
36 #ifdef TALLOC_BUILD_VERSION_MAJOR
37 #if (TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR)
38 #error "TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR"
42 #ifdef TALLOC_BUILD_VERSION_MINOR
43 #if (TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR)
44 #error "TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR"
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 ( \
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() */
70 #define TALLOC_ABORT(reason) abort()
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)))
77 # define discard_const_p(type, ptr) ((type *)(ptr))
81 /* these macros gain us a few percent of speed on gcc */
83 /* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
84 as its first argument */
86 #define likely(x) __builtin_expect(!!(x), 1)
89 #define unlikely(x) __builtin_expect(!!(x), 0)
96 #define unlikely(x) (x)
100 /* this null_context is only used if talloc_enable_leak_report() or
101 talloc_enable_leak_report_full() is called, otherwise it remains
104 static void *null_context
;
105 static void *autofree_context
;
107 struct talloc_reference_handle
{
108 struct talloc_reference_handle
*next
, *prev
;
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
;
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
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
, ...)
165 if (!talloc_log_fn
) {
170 message
= talloc_vasprintf(NULL
, fmt
, 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",
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));
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();
242 talloc_abort_unknown_value();
249 /* hook into the front of the list */
250 #define _TLIST_ADD(list, p) \
254 (p)->next = (p)->prev = NULL; \
256 (list)->prev = (p); \
257 (p)->next = (list); \
263 /* remove an element from a list - element doesn't have to be in list. */
264 #define _TLIST_REMOVE(list, p) \
266 if ((p) == (list)) { \
267 (list) = (p)->next; \
268 if (list) (list)->prev = NULL; \
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; \
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
)) {
288 tc
= talloc_chunk_from_ptr(ptr
);
289 while (tc
->prev
) tc
=tc
->prev
;
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
;
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
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
));
333 static struct talloc_chunk
*talloc_alloc_pool(struct talloc_chunk
*parent
,
336 struct talloc_chunk
*pool_ctx
= NULL
;
338 struct talloc_chunk
*result
;
341 if (parent
== NULL
) {
345 if (parent
->flags
& TALLOC_FLAG_POOL
) {
348 else if (parent
->flags
& TALLOC_FLAG_POOLMEM
) {
349 pool_ctx
= (struct talloc_chunk
*)parent
->pool
;
352 if (pool_ctx
== 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
) {
368 result
= (struct talloc_chunk
*)pool_ctx
->pool
;
370 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
371 VALGRIND_MAKE_MEM_UNDEFINED(result
, size
);
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;
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
)) {
399 if (context
!= NULL
) {
400 tc
= talloc_alloc_pool(talloc_chunk_from_ptr(context
),
405 tc
= (struct talloc_chunk
*)malloc(TC_HDR_SIZE
+size
);
406 if (unlikely(tc
== NULL
)) return NULL
;
407 tc
->flags
= TALLOC_MAGIC
;
412 tc
->destructor
= NULL
;
417 if (likely(context
)) {
418 struct talloc_chunk
*parent
= talloc_chunk_from_ptr(context
);
421 parent
->child
->parent
= NULL
;
422 tc
->next
= parent
->child
;
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
)) {
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
);
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
))) {
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
);
500 more efficient way to add a name to a pointer - the name must point to a
503 static inline void _talloc_set_name_const(const void *ptr
, const char *name
)
505 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
510 internal talloc_named_const()
512 static inline void *_talloc_named_const(const void *context
, size_t size
, const char *name
)
516 ptr
= __talloc(context
, size
);
517 if (unlikely(ptr
== NULL
)) {
521 _talloc_set_name_const(ptr
, name
);
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
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,
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
);
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
)) {
570 tc
= talloc_chunk_from_ptr(ptr
);
572 if (unlikely(tc
->refs
)) {
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
581 is_child
= talloc_is_parent(tc
->refs
, ptr
);
582 _talloc_free_internal(tc
->refs
, location
);
584 return _talloc_free_internal(ptr
, location
);
589 if (unlikely(tc
->flags
& TALLOC_FLAG_LOOP
)) {
590 /* we have a free loop - stop looping */
594 if (unlikely(tc
->destructor
)) {
595 talloc_destructor_t d
= tc
->destructor
;
596 if (d
== (talloc_destructor_t
)-1) {
599 tc
->destructor
= (talloc_destructor_t
)-1;
604 tc
->destructor
= NULL
;
608 _TLIST_REMOVE(tc
->parent
->child
, tc
);
609 if (tc
->parent
->child
) {
610 tc
->parent
->child
->parent
= tc
->parent
;
613 if (tc
->prev
) tc
->prev
->next
= tc
->next
;
614 if (tc
->next
) tc
->next
->prev
= tc
->prev
;
617 tc
->flags
|= TALLOC_FLAG_LOOP
;
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
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!");
662 *pool_object_count
-= 1;
664 if (*pool_object_count
== 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
)) {
687 if (unlikely(new_ctx
== NULL
)) {
688 new_ctx
= null_context
;
691 tc
= talloc_chunk_from_ptr(ptr
);
693 if (unlikely(new_ctx
== NULL
)) {
695 _TLIST_REMOVE(tc
->parent
->child
, tc
);
696 if (tc
->parent
->child
) {
697 tc
->parent
->child
->parent
= tc
->parent
;
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
);
715 _TLIST_REMOVE(tc
->parent
->child
, tc
);
716 if (tc
->parent
->child
) {
717 tc
->parent
->child
->parent
= tc
->parent
;
720 if (tc
->prev
) tc
->prev
->next
= tc
->next
;
721 if (tc
->next
) tc
->next
->prev
= tc
->prev
;
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
)) {
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",
752 for (h
=tc
->refs
; h
; h
=h
->next
) {
753 talloc_log("\treference at %s\n",
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
)) {
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
) {
787 return discard_const_p(void, ptr
);
791 /* it wasn't a parent */
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
);
812 if (context
== NULL
) break;
813 } else if (TC_PTR_FROM_CHUNK(p
) == context
) {
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
;
837 if (context
== NULL
) {
838 context
= null_context
;
841 if (talloc_unreference(context
, ptr
) == 0) {
845 if (context
== NULL
) {
846 if (talloc_parent_chunk(ptr
) != NULL
) {
850 if (talloc_chunk_from_ptr(context
) != talloc_parent_chunk(ptr
)) {
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
);
863 new_parent
= TC_PTR_FROM_CHUNK(new_p
);
868 if (talloc_unreference(new_parent
, ptr
) != 0) {
872 _talloc_steal_internal(new_parent
, ptr
);
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");
893 add a name to an existing pointer
895 const char *talloc_set_name(const void *ptr
, const char *fmt
, ...)
900 name
= talloc_set_name_v(ptr
, fmt
, ap
);
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
911 void *talloc_named(const void *context
, size_t size
, const char *fmt
, ...)
917 ptr
= __talloc(context
, size
);
918 if (unlikely(ptr
== NULL
)) return NULL
;
921 name
= talloc_set_name_v(ptr
, fmt
, ap
);
924 if (unlikely(name
== NULL
)) {
925 _talloc_free_internal(ptr
, __location__
);
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
)) {
941 if (likely(tc
->name
)) {
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
)
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
);
963 static void talloc_abort_type_missmatch(const char *location
,
965 const char *expected
)
969 reason
= talloc_asprintf(NULL
,
970 "%s: Type mismatch: name[%s] expected[%s]",
975 reason
= "Type mismatch";
978 talloc_abort(reason
);
981 void *_talloc_get_type_abort(const void *ptr
, const char *name
, const char *location
)
985 if (unlikely(ptr
== NULL
)) {
986 talloc_abort_type_missmatch(location
, NULL
, name
);
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
);
1000 this is for compatibility with older versions of talloc
1002 void *talloc_init(const char *fmt
, ...)
1009 * samba3 expects talloc_report_depth_cb(NULL, ...)
1010 * reports all talloc'ed memory, so we need to enable
1013 talloc_enable_null_tracking();
1015 ptr
= __talloc(NULL
, 0);
1016 if (unlikely(ptr
== NULL
)) return NULL
;
1019 name
= talloc_set_name_v(ptr
, fmt
, ap
);
1022 if (unlikely(name
== NULL
)) {
1023 _talloc_free_internal(ptr
, __location__
);
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
)) {
1043 tc
= talloc_chunk_from_ptr(ptr
);
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
);
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
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
)) {
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",
1126 for (h
=tc
->refs
; h
; h
=h
->next
) {
1127 talloc_log("\treference at %s\n",
1133 return _talloc_free_internal(ptr
, location
);
1139 A talloc version of realloc. The context argument is only used if
1142 void *_talloc_realloc(const void *context
, void *ptr
, size_t size
, const char *name
)
1144 struct talloc_chunk
*tc
;
1146 bool malloced
= false;
1148 /* size zero is equivalent to free() */
1149 if (unlikely(size
== 0)) {
1150 talloc_unlink(context
, ptr
);
1154 if (unlikely(size
>= MAX_TALLOC_SIZE
)) {
1158 /* realloc(NULL) is equivalent to malloc() */
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
)) {
1170 /* don't let anybody try to realloc a talloc_pool */
1171 if (unlikely(tc
->flags
& TALLOC_FLAG_POOL
)) {
1175 /* don't shrink if we have less than 1k to gain */
1176 if ((size
< tc
->size
) && ((tc
->size
- size
) < 1024)) {
1181 /* by resetting magic we catch users of the old memory */
1182 tc
->flags
|= TALLOC_FLAG_FREE
;
1185 new_ptr
= malloc(size
+ TC_HDR_SIZE
);
1187 memcpy(new_ptr
, tc
, MIN(tc
->size
, size
) + TC_HDR_SIZE
);
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
*)
1197 if (new_ptr
== NULL
) {
1198 new_ptr
= malloc(TC_HDR_SIZE
+size
);
1203 memcpy(new_ptr
, tc
, MIN(tc
->size
,size
) + TC_HDR_SIZE
);
1207 new_ptr
= realloc(tc
, size
+ TC_HDR_SIZE
);
1210 if (unlikely(!new_ptr
)) {
1211 tc
->flags
&= ~TALLOC_FLAG_FREE
;
1215 tc
= (struct talloc_chunk
*)new_ptr
;
1216 tc
->flags
&= ~TALLOC_FLAG_FREE
;
1218 tc
->flags
&= ~TALLOC_FLAG_POOLMEM
;
1221 tc
->parent
->child
= tc
;
1224 tc
->child
->parent
= tc
;
1228 tc
->prev
->next
= tc
;
1231 tc
->next
->prev
= tc
;
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
));
1253 return the total size of a talloc pool (subtree)
1255 size_t talloc_total_size(const void *ptr
)
1258 struct talloc_chunk
*c
, *tc
;
1267 tc
= talloc_chunk_from_ptr(ptr
);
1269 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
1273 tc
->flags
|= TALLOC_FLAG_LOOP
;
1275 if (likely(tc
->name
!= TALLOC_MAGIC_REFERENCE
)) {
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
;
1288 return the total number of blocks in a talloc pool (subtree)
1290 size_t talloc_total_blocks(const void *ptr
)
1293 struct talloc_chunk
*c
, *tc
;
1302 tc
= talloc_chunk_from_ptr(ptr
);
1304 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
1308 tc
->flags
|= TALLOC_FLAG_LOOP
;
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
;
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
;
1329 for (h
=tc
->refs
;h
;h
=h
->next
) {
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
,
1342 void *private_data
),
1345 struct talloc_chunk
*c
, *tc
;
1350 if (ptr
== NULL
) return;
1352 tc
= talloc_chunk_from_ptr(ptr
);
1354 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
1358 callback(ptr
, depth
, max_depth
, 0, private_data
);
1360 if (max_depth
>= 0 && depth
>= max_depth
) {
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
);
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
;
1382 fprintf(f
, "%*sreference to: %s\n", depth
*4, "", name
);
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
));
1394 fprintf(f
, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
1397 (unsigned long)talloc_total_size(ptr
),
1398 (unsigned long)talloc_total_blocks(ptr
),
1399 (int)talloc_reference_count(ptr
), ptr
);
1402 fprintf(f
, "content: ");
1403 if (talloc_total_size(ptr
)) {
1404 int tot
= talloc_total_size(ptr
);
1407 for (i
= 0; i
< tot
; i
++) {
1408 if ((((char *)ptr
)[i
] > 31) && (((char *)ptr
)[i
] < 126)) {
1409 fprintf(f
, "%c", ((char *)ptr
)[i
]);
1411 fprintf(f
, "~%02x", ((char *)ptr
)[i
]);
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
)
1425 talloc_report_depth_cb(ptr
, depth
, max_depth
, talloc_report_depth_FILE_helper
, f
);
1431 report on memory usage by all children of a pointer, giving a full tree view
1433 void talloc_report_full(const void *ptr
, FILE *f
)
1435 talloc_report_depth_file(ptr
, 0, -1, f
);
1439 report on memory usage by all children of a pointer
1441 void talloc_report(const void *ptr
, FILE *f
)
1443 talloc_report_depth_file(ptr
, 0, 1, f
);
1447 report on any memory hanging off the null context
1449 static void talloc_report_null(void)
1451 if (talloc_total_size(null_context
) != 0) {
1452 talloc_report(null_context
, stderr
);
1457 report on any memory hanging off the null context
1459 static void talloc_report_null_full(void)
1461 if (talloc_total_size(null_context
) != 0) {
1462 talloc_report_full(null_context
, stderr
);
1467 enable tracking of the NULL context
1469 void talloc_enable_null_tracking(void)
1471 if (null_context
== NULL
) {
1472 null_context
= _talloc_named_const(NULL
, 0, "null_context");
1473 if (autofree_context
!= NULL
) {
1474 talloc_reparent(NULL
, null_context
, autofree_context
);
1480 enable tracking of the NULL context, not moving the autofree context
1481 into the NULL context. This is needed for the talloc testsuite
1483 void talloc_enable_null_tracking_no_autofree(void)
1485 if (null_context
== NULL
) {
1486 null_context
= _talloc_named_const(NULL
, 0, "null_context");
1491 disable tracking of the NULL context
1493 void talloc_disable_null_tracking(void)
1495 if (null_context
!= NULL
) {
1496 /* we have to move any children onto the real NULL
1498 struct talloc_chunk
*tc
, *tc2
;
1499 tc
= talloc_chunk_from_ptr(null_context
);
1500 for (tc2
= tc
->child
; tc2
; tc2
=tc2
->next
) {
1501 if (tc2
->parent
== tc
) tc2
->parent
= NULL
;
1502 if (tc2
->prev
== tc
) tc2
->prev
= NULL
;
1504 for (tc2
= tc
->next
; tc2
; tc2
=tc2
->next
) {
1505 if (tc2
->parent
== tc
) tc2
->parent
= NULL
;
1506 if (tc2
->prev
== tc
) tc2
->prev
= NULL
;
1511 talloc_free(null_context
);
1512 null_context
= NULL
;
1516 enable leak reporting on exit
1518 void talloc_enable_leak_report(void)
1520 talloc_enable_null_tracking();
1521 atexit(talloc_report_null
);
1525 enable full leak reporting on exit
1527 void talloc_enable_leak_report_full(void)
1529 talloc_enable_null_tracking();
1530 atexit(talloc_report_null_full
);
1534 talloc and zero memory.
1536 void *_talloc_zero(const void *ctx
, size_t size
, const char *name
)
1538 void *p
= _talloc_named_const(ctx
, size
, name
);
1541 memset(p
, '\0', size
);
1548 memdup with a talloc.
1550 void *_talloc_memdup(const void *t
, const void *p
, size_t size
, const char *name
)
1552 void *newp
= _talloc_named_const(t
, size
, name
);
1555 memcpy(newp
, p
, size
);
1561 static inline char *__talloc_strlendup(const void *t
, const char *p
, size_t len
)
1565 ret
= (char *)__talloc(t
, len
+ 1);
1566 if (unlikely(!ret
)) return NULL
;
1568 memcpy(ret
, p
, len
);
1571 _talloc_set_name_const(ret
, ret
);
1576 strdup with a talloc
1578 char *talloc_strdup(const void *t
, const char *p
)
1580 if (unlikely(!p
)) return NULL
;
1581 return __talloc_strlendup(t
, p
, strlen(p
));
1585 strndup with a talloc
1587 char *talloc_strndup(const void *t
, const char *p
, size_t n
)
1589 if (unlikely(!p
)) return NULL
;
1590 return __talloc_strlendup(t
, p
, strnlen(p
, n
));
1593 static inline char *__talloc_strlendup_append(char *s
, size_t slen
,
1594 const char *a
, size_t alen
)
1598 ret
= talloc_realloc(NULL
, s
, char, slen
+ alen
+ 1);
1599 if (unlikely(!ret
)) return NULL
;
1601 /* append the string and the trailing \0 */
1602 memcpy(&ret
[slen
], a
, alen
);
1605 _talloc_set_name_const(ret
, ret
);
1610 * Appends at the end of the string.
1612 char *talloc_strdup_append(char *s
, const char *a
)
1615 return talloc_strdup(NULL
, a
);
1622 return __talloc_strlendup_append(s
, strlen(s
), a
, strlen(a
));
1626 * Appends at the end of the talloc'ed buffer,
1627 * not the end of the string.
1629 char *talloc_strdup_append_buffer(char *s
, const char *a
)
1634 return talloc_strdup(NULL
, a
);
1641 slen
= talloc_get_size(s
);
1642 if (likely(slen
> 0)) {
1646 return __talloc_strlendup_append(s
, slen
, a
, strlen(a
));
1650 * Appends at the end of the string.
1652 char *talloc_strndup_append(char *s
, const char *a
, size_t n
)
1655 return talloc_strdup(NULL
, a
);
1662 return __talloc_strlendup_append(s
, strlen(s
), a
, strnlen(a
, n
));
1666 * Appends at the end of the talloc'ed buffer,
1667 * not the end of the string.
1669 char *talloc_strndup_append_buffer(char *s
, const char *a
, size_t n
)
1674 return talloc_strdup(NULL
, a
);
1681 slen
= talloc_get_size(s
);
1682 if (likely(slen
> 0)) {
1686 return __talloc_strlendup_append(s
, slen
, a
, strnlen(a
, n
));
1689 #ifndef HAVE_VA_COPY
1690 #ifdef HAVE___VA_COPY
1691 #define va_copy(dest, src) __va_copy(dest, src)
1693 #define va_copy(dest, src) (dest) = (src)
1697 char *talloc_vasprintf(const void *t
, const char *fmt
, va_list ap
)
1704 /* this call looks strange, but it makes it work on older solaris boxes */
1706 len
= vsnprintf(&c
, 1, fmt
, ap2
);
1708 if (unlikely(len
< 0)) {
1712 ret
= (char *)__talloc(t
, len
+1);
1713 if (unlikely(!ret
)) return NULL
;
1716 vsnprintf(ret
, len
+1, fmt
, ap2
);
1719 _talloc_set_name_const(ret
, ret
);
1725 Perform string formatting, and return a pointer to newly allocated
1726 memory holding the result, inside a memory pool.
1728 char *talloc_asprintf(const void *t
, const char *fmt
, ...)
1734 ret
= talloc_vasprintf(t
, fmt
, ap
);
1739 static inline char *__talloc_vaslenprintf_append(char *s
, size_t slen
,
1740 const char *fmt
, va_list ap
)
1741 PRINTF_ATTRIBUTE(3,0);
1743 static inline char *__talloc_vaslenprintf_append(char *s
, size_t slen
,
1744 const char *fmt
, va_list ap
)
1751 alen
= vsnprintf(&c
, 1, fmt
, ap2
);
1755 /* Either the vsnprintf failed or the format resulted in
1756 * no characters being formatted. In the former case, we
1757 * ought to return NULL, in the latter we ought to return
1758 * the original string. Most current callers of this
1759 * function expect it to never return NULL.
1764 s
= talloc_realloc(NULL
, s
, char, slen
+ alen
+ 1);
1765 if (!s
) return NULL
;
1768 vsnprintf(s
+ slen
, alen
+ 1, fmt
, ap2
);
1771 _talloc_set_name_const(s
, s
);
1776 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1777 * and return @p s, which may have moved. Good for gradually
1778 * accumulating output into a string buffer. Appends at the end
1781 char *talloc_vasprintf_append(char *s
, const char *fmt
, va_list ap
)
1784 return talloc_vasprintf(NULL
, fmt
, ap
);
1787 return __talloc_vaslenprintf_append(s
, strlen(s
), fmt
, ap
);
1791 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1792 * and return @p s, which may have moved. Always appends at the
1793 * end of the talloc'ed buffer, not the end of the string.
1795 char *talloc_vasprintf_append_buffer(char *s
, const char *fmt
, va_list ap
)
1800 return talloc_vasprintf(NULL
, fmt
, ap
);
1803 slen
= talloc_get_size(s
);
1804 if (likely(slen
> 0)) {
1808 return __talloc_vaslenprintf_append(s
, slen
, fmt
, ap
);
1812 Realloc @p s to append the formatted result of @p fmt and return @p
1813 s, which may have moved. Good for gradually accumulating output
1814 into a string buffer.
1816 char *talloc_asprintf_append(char *s
, const char *fmt
, ...)
1821 s
= talloc_vasprintf_append(s
, fmt
, ap
);
1827 Realloc @p s to append the formatted result of @p fmt and return @p
1828 s, which may have moved. Good for gradually accumulating output
1831 char *talloc_asprintf_append_buffer(char *s
, const char *fmt
, ...)
1836 s
= talloc_vasprintf_append_buffer(s
, fmt
, ap
);
1842 alloc an array, checking for integer overflow in the array size
1844 void *_talloc_array(const void *ctx
, size_t el_size
, unsigned count
, const char *name
)
1846 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
1849 return _talloc_named_const(ctx
, el_size
* count
, name
);
1853 alloc an zero array, checking for integer overflow in the array size
1855 void *_talloc_zero_array(const void *ctx
, size_t el_size
, unsigned count
, const char *name
)
1857 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
1860 return _talloc_zero(ctx
, el_size
* count
, name
);
1864 realloc an array, checking for integer overflow in the array size
1866 void *_talloc_realloc_array(const void *ctx
, void *ptr
, size_t el_size
, unsigned count
, const char *name
)
1868 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
1871 return _talloc_realloc(ctx
, ptr
, el_size
* count
, name
);
1875 a function version of talloc_realloc(), so it can be passed as a function pointer
1876 to libraries that want a realloc function (a realloc function encapsulates
1877 all the basic capabilities of an allocation library, which is why this is useful)
1879 void *talloc_realloc_fn(const void *context
, void *ptr
, size_t size
)
1881 return _talloc_realloc(context
, ptr
, size
, NULL
);
1885 static int talloc_autofree_destructor(void *ptr
)
1887 autofree_context
= NULL
;
1891 static void talloc_autofree(void)
1893 talloc_free(autofree_context
);
1897 return a context which will be auto-freed on exit
1898 this is useful for reducing the noise in leak reports
1900 void *talloc_autofree_context(void)
1902 if (autofree_context
== NULL
) {
1903 autofree_context
= _talloc_named_const(NULL
, 0, "autofree_context");
1904 talloc_set_destructor(autofree_context
, talloc_autofree_destructor
);
1905 atexit(talloc_autofree
);
1907 return autofree_context
;
1910 size_t talloc_get_size(const void *context
)
1912 struct talloc_chunk
*tc
;
1914 if (context
== NULL
) {
1915 context
= null_context
;
1917 if (context
== NULL
) {
1921 tc
= talloc_chunk_from_ptr(context
);
1927 find a parent of this context that has the given name, if any
1929 void *talloc_find_parent_byname(const void *context
, const char *name
)
1931 struct talloc_chunk
*tc
;
1933 if (context
== NULL
) {
1937 tc
= talloc_chunk_from_ptr(context
);
1939 if (tc
->name
&& strcmp(tc
->name
, name
) == 0) {
1940 return TC_PTR_FROM_CHUNK(tc
);
1942 while (tc
&& tc
->prev
) tc
= tc
->prev
;
1951 show the parentage of a context
1953 void talloc_show_parents(const void *context
, FILE *file
)
1955 struct talloc_chunk
*tc
;
1957 if (context
== NULL
) {
1958 fprintf(file
, "talloc no parents for NULL\n");
1962 tc
= talloc_chunk_from_ptr(context
);
1963 fprintf(file
, "talloc parents of '%s'\n", talloc_get_name(context
));
1965 fprintf(file
, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc
)));
1966 while (tc
&& tc
->prev
) tc
= tc
->prev
;
1975 return 1 if ptr is a parent of context
1977 int talloc_is_parent(const void *context
, const void *ptr
)
1979 struct talloc_chunk
*tc
;
1981 if (context
== NULL
) {
1985 tc
= talloc_chunk_from_ptr(context
);
1987 if (TC_PTR_FROM_CHUNK(tc
) == ptr
) return 1;
1988 while (tc
&& tc
->prev
) tc
= tc
->prev
;