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 _PUBLIC_
int talloc_version_major(void)
144 return TALLOC_VERSION_MAJOR
;
147 _PUBLIC_
int talloc_version_minor(void)
149 return TALLOC_VERSION_MINOR
;
152 static void (*talloc_log_fn
)(const char *message
);
154 _PUBLIC_
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 _PUBLIC_
void talloc_set_log_stderr(void)
184 talloc_set_log_fn(talloc_log_stderr
);
187 static void (*talloc_abort_fn
)(const char *reason
);
189 _PUBLIC_
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 _PUBLIC_
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 _PUBLIC_
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 _PUBLIC_
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 _PUBLIC_
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 _PUBLIC_
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 _PUBLIC_
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 _PUBLIC_
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",
759 /* this test is probably too expensive to have on in the
760 normal build, but it useful for debugging */
761 if (talloc_is_parent(new_ctx
, ptr
)) {
762 talloc_log("WARNING: stealing into talloc child at %s\n", location
);
766 return _talloc_steal_internal(new_ctx
, ptr
);
770 this is like a talloc_steal(), but you must supply the old
771 parent. This resolves the ambiguity in a talloc_steal() which is
772 called on a context that has more than one parent (via references)
774 The old parent can be either a reference or a parent
776 _PUBLIC_
void *talloc_reparent(const void *old_parent
, const void *new_parent
, const void *ptr
)
778 struct talloc_chunk
*tc
;
779 struct talloc_reference_handle
*h
;
781 if (unlikely(ptr
== NULL
)) {
785 if (old_parent
== talloc_parent(ptr
)) {
786 return _talloc_steal_internal(new_parent
, ptr
);
789 tc
= talloc_chunk_from_ptr(ptr
);
790 for (h
=tc
->refs
;h
;h
=h
->next
) {
791 if (talloc_parent(h
) == old_parent
) {
792 if (_talloc_steal_internal(new_parent
, h
) != h
) {
795 return discard_const_p(void, ptr
);
799 /* it wasn't a parent */
804 remove a secondary reference to a pointer. This undo's what
805 talloc_reference() has done. The context and pointer arguments
806 must match those given to a talloc_reference()
808 static inline int talloc_unreference(const void *context
, const void *ptr
)
810 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
811 struct talloc_reference_handle
*h
;
813 if (unlikely(context
== NULL
)) {
814 context
= null_context
;
817 for (h
=tc
->refs
;h
;h
=h
->next
) {
818 struct talloc_chunk
*p
= talloc_parent_chunk(h
);
820 if (context
== NULL
) break;
821 } else if (TC_PTR_FROM_CHUNK(p
) == context
) {
829 return _talloc_free_internal(h
, __location__
);
833 remove a specific parent context from a pointer. This is a more
834 controlled varient of talloc_free()
836 _PUBLIC_
int talloc_unlink(const void *context
, void *ptr
)
838 struct talloc_chunk
*tc_p
, *new_p
;
845 if (context
== NULL
) {
846 context
= null_context
;
849 if (talloc_unreference(context
, ptr
) == 0) {
853 if (context
== NULL
) {
854 if (talloc_parent_chunk(ptr
) != NULL
) {
858 if (talloc_chunk_from_ptr(context
) != talloc_parent_chunk(ptr
)) {
863 tc_p
= talloc_chunk_from_ptr(ptr
);
865 if (tc_p
->refs
== NULL
) {
866 return _talloc_free_internal(ptr
, __location__
);
869 new_p
= talloc_parent_chunk(tc_p
->refs
);
871 new_parent
= TC_PTR_FROM_CHUNK(new_p
);
876 if (talloc_unreference(new_parent
, ptr
) != 0) {
880 _talloc_steal_internal(new_parent
, ptr
);
886 add a name to an existing pointer - va_list version
888 static inline const char *talloc_set_name_v(const void *ptr
, const char *fmt
, va_list ap
) PRINTF_ATTRIBUTE(2,0);
890 static inline const char *talloc_set_name_v(const void *ptr
, const char *fmt
, va_list ap
)
892 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
893 tc
->name
= talloc_vasprintf(ptr
, fmt
, ap
);
894 if (likely(tc
->name
)) {
895 _talloc_set_name_const(tc
->name
, ".name");
901 add a name to an existing pointer
903 _PUBLIC_
const char *talloc_set_name(const void *ptr
, const char *fmt
, ...)
908 name
= talloc_set_name_v(ptr
, fmt
, ap
);
915 create a named talloc pointer. Any talloc pointer can be named, and
916 talloc_named() operates just like talloc() except that it allows you
919 _PUBLIC_
void *talloc_named(const void *context
, size_t size
, const char *fmt
, ...)
925 ptr
= __talloc(context
, size
);
926 if (unlikely(ptr
== NULL
)) return NULL
;
929 name
= talloc_set_name_v(ptr
, fmt
, ap
);
932 if (unlikely(name
== NULL
)) {
933 _talloc_free_internal(ptr
, __location__
);
941 return the name of a talloc ptr, or "UNNAMED"
943 _PUBLIC_
const char *talloc_get_name(const void *ptr
)
945 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
946 if (unlikely(tc
->name
== TALLOC_MAGIC_REFERENCE
)) {
949 if (likely(tc
->name
)) {
957 check if a pointer has the given name. If it does, return the pointer,
958 otherwise return NULL
960 _PUBLIC_
void *talloc_check_name(const void *ptr
, const char *name
)
963 if (unlikely(ptr
== NULL
)) return NULL
;
964 pname
= talloc_get_name(ptr
);
965 if (likely(pname
== name
|| strcmp(pname
, name
) == 0)) {
966 return discard_const_p(void, ptr
);
971 static void talloc_abort_type_missmatch(const char *location
,
973 const char *expected
)
977 reason
= talloc_asprintf(NULL
,
978 "%s: Type mismatch: name[%s] expected[%s]",
983 reason
= "Type mismatch";
986 talloc_abort(reason
);
989 _PUBLIC_
void *_talloc_get_type_abort(const void *ptr
, const char *name
, const char *location
)
993 if (unlikely(ptr
== NULL
)) {
994 talloc_abort_type_missmatch(location
, NULL
, name
);
998 pname
= talloc_get_name(ptr
);
999 if (likely(pname
== name
|| strcmp(pname
, name
) == 0)) {
1000 return discard_const_p(void, ptr
);
1003 talloc_abort_type_missmatch(location
, pname
, name
);
1008 this is for compatibility with older versions of talloc
1010 _PUBLIC_
void *talloc_init(const char *fmt
, ...)
1017 * samba3 expects talloc_report_depth_cb(NULL, ...)
1018 * reports all talloc'ed memory, so we need to enable
1021 talloc_enable_null_tracking();
1023 ptr
= __talloc(NULL
, 0);
1024 if (unlikely(ptr
== NULL
)) return NULL
;
1027 name
= talloc_set_name_v(ptr
, fmt
, ap
);
1030 if (unlikely(name
== NULL
)) {
1031 _talloc_free_internal(ptr
, __location__
);
1039 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
1040 should probably not be used in new code. It's in here to keep the talloc
1041 code consistent across Samba 3 and 4.
1043 _PUBLIC_
void talloc_free_children(void *ptr
)
1045 struct talloc_chunk
*tc
;
1047 if (unlikely(ptr
== NULL
)) {
1051 tc
= talloc_chunk_from_ptr(ptr
);
1054 /* we need to work out who will own an abandoned child
1055 if it cannot be freed. In priority order, the first
1056 choice is owner of any remaining reference to this
1057 pointer, the second choice is our parent, and the
1058 final choice is the null context. */
1059 void *child
= TC_PTR_FROM_CHUNK(tc
->child
);
1060 const void *new_parent
= null_context
;
1061 if (unlikely(tc
->child
->refs
)) {
1062 struct talloc_chunk
*p
= talloc_parent_chunk(tc
->child
->refs
);
1063 if (p
) new_parent
= TC_PTR_FROM_CHUNK(p
);
1065 if (unlikely(talloc_free(child
) == -1)) {
1066 if (new_parent
== null_context
) {
1067 struct talloc_chunk
*p
= talloc_parent_chunk(ptr
);
1068 if (p
) new_parent
= TC_PTR_FROM_CHUNK(p
);
1070 _talloc_steal_internal(new_parent
, child
);
1074 if ((tc
->flags
& TALLOC_FLAG_POOL
)
1075 && (*talloc_pool_objectcount(tc
) == 1)) {
1076 tc
->pool
= ((char *)tc
+ TC_HDR_SIZE
+ TALLOC_POOL_HDR_SIZE
);
1077 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
1078 VALGRIND_MAKE_MEM_NOACCESS(
1079 tc
->pool
, tc
->size
- TALLOC_POOL_HDR_SIZE
);
1085 Allocate a bit of memory as a child of an existing pointer
1087 _PUBLIC_
void *_talloc(const void *context
, size_t size
)
1089 return __talloc(context
, size
);
1093 externally callable talloc_set_name_const()
1095 _PUBLIC_
void talloc_set_name_const(const void *ptr
, const char *name
)
1097 _talloc_set_name_const(ptr
, name
);
1101 create a named talloc pointer. Any talloc pointer can be named, and
1102 talloc_named() operates just like talloc() except that it allows you
1103 to name the pointer.
1105 _PUBLIC_
void *talloc_named_const(const void *context
, size_t size
, const char *name
)
1107 return _talloc_named_const(context
, size
, name
);
1111 free a talloc pointer. This also frees all child pointers of this
1114 return 0 if the memory is actually freed, otherwise -1. The memory
1115 will not be freed if the ref_count is > 1 or the destructor (if
1116 any) returns non-zero
1118 _PUBLIC_
int _talloc_free(void *ptr
, const char *location
)
1120 struct talloc_chunk
*tc
;
1122 if (unlikely(ptr
== NULL
)) {
1126 tc
= talloc_chunk_from_ptr(ptr
);
1128 if (unlikely(tc
->refs
!= NULL
)) {
1129 struct talloc_reference_handle
*h
;
1131 if (talloc_parent(ptr
) == null_context
&& tc
->refs
->next
== NULL
) {
1132 /* in this case we do know which parent should
1133 get this pointer, as there is really only
1135 return talloc_unlink(null_context
, ptr
);
1138 talloc_log("ERROR: talloc_free with references at %s\n",
1141 for (h
=tc
->refs
; h
; h
=h
->next
) {
1142 talloc_log("\treference at %s\n",
1148 return _talloc_free_internal(ptr
, location
);
1154 A talloc version of realloc. The context argument is only used if
1157 _PUBLIC_
void *_talloc_realloc(const void *context
, void *ptr
, size_t size
, const char *name
)
1159 struct talloc_chunk
*tc
;
1161 bool malloced
= false;
1163 /* size zero is equivalent to free() */
1164 if (unlikely(size
== 0)) {
1165 talloc_unlink(context
, ptr
);
1169 if (unlikely(size
>= MAX_TALLOC_SIZE
)) {
1173 /* realloc(NULL) is equivalent to malloc() */
1175 return _talloc_named_const(context
, size
, name
);
1178 tc
= talloc_chunk_from_ptr(ptr
);
1180 /* don't allow realloc on referenced pointers */
1181 if (unlikely(tc
->refs
)) {
1185 /* don't let anybody try to realloc a talloc_pool */
1186 if (unlikely(tc
->flags
& TALLOC_FLAG_POOL
)) {
1190 /* don't shrink if we have less than 1k to gain */
1191 if ((size
< tc
->size
) && ((tc
->size
- size
) < 1024)) {
1196 /* by resetting magic we catch users of the old memory */
1197 tc
->flags
|= TALLOC_FLAG_FREE
;
1200 new_ptr
= malloc(size
+ TC_HDR_SIZE
);
1202 memcpy(new_ptr
, tc
, MIN(tc
->size
, size
) + TC_HDR_SIZE
);
1206 if (tc
->flags
& TALLOC_FLAG_POOLMEM
) {
1208 new_ptr
= talloc_alloc_pool(tc
, size
+ TC_HDR_SIZE
);
1209 *talloc_pool_objectcount((struct talloc_chunk
*)
1212 if (new_ptr
== NULL
) {
1213 new_ptr
= malloc(TC_HDR_SIZE
+size
);
1218 memcpy(new_ptr
, tc
, MIN(tc
->size
,size
) + TC_HDR_SIZE
);
1222 new_ptr
= realloc(tc
, size
+ TC_HDR_SIZE
);
1225 if (unlikely(!new_ptr
)) {
1226 tc
->flags
&= ~TALLOC_FLAG_FREE
;
1230 tc
= (struct talloc_chunk
*)new_ptr
;
1231 tc
->flags
&= ~TALLOC_FLAG_FREE
;
1233 tc
->flags
&= ~TALLOC_FLAG_POOLMEM
;
1236 tc
->parent
->child
= tc
;
1239 tc
->child
->parent
= tc
;
1243 tc
->prev
->next
= tc
;
1246 tc
->next
->prev
= tc
;
1250 _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc
), name
);
1252 return TC_PTR_FROM_CHUNK(tc
);
1256 a wrapper around talloc_steal() for situations where you are moving a pointer
1257 between two structures, and want the old pointer to be set to NULL
1259 _PUBLIC_
void *_talloc_move(const void *new_ctx
, const void *_pptr
)
1261 const void **pptr
= discard_const_p(const void *,_pptr
);
1262 void *ret
= talloc_steal(new_ctx
, discard_const_p(void, *pptr
));
1268 return the total size of a talloc pool (subtree)
1270 _PUBLIC_
size_t talloc_total_size(const void *ptr
)
1273 struct talloc_chunk
*c
, *tc
;
1282 tc
= talloc_chunk_from_ptr(ptr
);
1284 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
1288 tc
->flags
|= TALLOC_FLAG_LOOP
;
1290 if (likely(tc
->name
!= TALLOC_MAGIC_REFERENCE
)) {
1293 for (c
=tc
->child
;c
;c
=c
->next
) {
1294 total
+= talloc_total_size(TC_PTR_FROM_CHUNK(c
));
1297 tc
->flags
&= ~TALLOC_FLAG_LOOP
;
1303 return the total number of blocks in a talloc pool (subtree)
1305 _PUBLIC_
size_t talloc_total_blocks(const void *ptr
)
1308 struct talloc_chunk
*c
, *tc
;
1317 tc
= talloc_chunk_from_ptr(ptr
);
1319 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
1323 tc
->flags
|= TALLOC_FLAG_LOOP
;
1326 for (c
=tc
->child
;c
;c
=c
->next
) {
1327 total
+= talloc_total_blocks(TC_PTR_FROM_CHUNK(c
));
1330 tc
->flags
&= ~TALLOC_FLAG_LOOP
;
1336 return the number of external references to a pointer
1338 _PUBLIC_
size_t talloc_reference_count(const void *ptr
)
1340 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
1341 struct talloc_reference_handle
*h
;
1344 for (h
=tc
->refs
;h
;h
=h
->next
) {
1351 report on memory usage by all children of a pointer, giving a full tree view
1353 _PUBLIC_
void talloc_report_depth_cb(const void *ptr
, int depth
, int max_depth
,
1354 void (*callback
)(const void *ptr
,
1355 int depth
, int max_depth
,
1357 void *private_data
),
1360 struct talloc_chunk
*c
, *tc
;
1365 if (ptr
== NULL
) return;
1367 tc
= talloc_chunk_from_ptr(ptr
);
1369 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
1373 callback(ptr
, depth
, max_depth
, 0, private_data
);
1375 if (max_depth
>= 0 && depth
>= max_depth
) {
1379 tc
->flags
|= TALLOC_FLAG_LOOP
;
1380 for (c
=tc
->child
;c
;c
=c
->next
) {
1381 if (c
->name
== TALLOC_MAGIC_REFERENCE
) {
1382 struct talloc_reference_handle
*h
= (struct talloc_reference_handle
*)TC_PTR_FROM_CHUNK(c
);
1383 callback(h
->ptr
, depth
+ 1, max_depth
, 1, private_data
);
1385 talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c
), depth
+ 1, max_depth
, callback
, private_data
);
1388 tc
->flags
&= ~TALLOC_FLAG_LOOP
;
1391 static void talloc_report_depth_FILE_helper(const void *ptr
, int depth
, int max_depth
, int is_ref
, void *_f
)
1393 const char *name
= talloc_get_name(ptr
);
1394 FILE *f
= (FILE *)_f
;
1397 fprintf(f
, "%*sreference to: %s\n", depth
*4, "", name
);
1402 fprintf(f
,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n",
1403 (max_depth
< 0 ? "full " :""), name
,
1404 (unsigned long)talloc_total_size(ptr
),
1405 (unsigned long)talloc_total_blocks(ptr
));
1409 fprintf(f
, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
1412 (unsigned long)talloc_total_size(ptr
),
1413 (unsigned long)talloc_total_blocks(ptr
),
1414 (int)talloc_reference_count(ptr
), ptr
);
1417 fprintf(f
, "content: ");
1418 if (talloc_total_size(ptr
)) {
1419 int tot
= talloc_total_size(ptr
);
1422 for (i
= 0; i
< tot
; i
++) {
1423 if ((((char *)ptr
)[i
] > 31) && (((char *)ptr
)[i
] < 126)) {
1424 fprintf(f
, "%c", ((char *)ptr
)[i
]);
1426 fprintf(f
, "~%02x", ((char *)ptr
)[i
]);
1435 report on memory usage by all children of a pointer, giving a full tree view
1437 _PUBLIC_
void talloc_report_depth_file(const void *ptr
, int depth
, int max_depth
, FILE *f
)
1440 talloc_report_depth_cb(ptr
, depth
, max_depth
, talloc_report_depth_FILE_helper
, f
);
1446 report on memory usage by all children of a pointer, giving a full tree view
1448 _PUBLIC_
void talloc_report_full(const void *ptr
, FILE *f
)
1450 talloc_report_depth_file(ptr
, 0, -1, f
);
1454 report on memory usage by all children of a pointer
1456 _PUBLIC_
void talloc_report(const void *ptr
, FILE *f
)
1458 talloc_report_depth_file(ptr
, 0, 1, f
);
1462 report on any memory hanging off the null context
1464 static void talloc_report_null(void)
1466 if (talloc_total_size(null_context
) != 0) {
1467 talloc_report(null_context
, stderr
);
1472 report on any memory hanging off the null context
1474 static void talloc_report_null_full(void)
1476 if (talloc_total_size(null_context
) != 0) {
1477 talloc_report_full(null_context
, stderr
);
1482 enable tracking of the NULL context
1484 _PUBLIC_
void talloc_enable_null_tracking(void)
1486 if (null_context
== NULL
) {
1487 null_context
= _talloc_named_const(NULL
, 0, "null_context");
1488 if (autofree_context
!= NULL
) {
1489 talloc_reparent(NULL
, null_context
, autofree_context
);
1495 enable tracking of the NULL context, not moving the autofree context
1496 into the NULL context. This is needed for the talloc testsuite
1498 _PUBLIC_
void talloc_enable_null_tracking_no_autofree(void)
1500 if (null_context
== NULL
) {
1501 null_context
= _talloc_named_const(NULL
, 0, "null_context");
1506 disable tracking of the NULL context
1508 _PUBLIC_
void talloc_disable_null_tracking(void)
1510 if (null_context
!= NULL
) {
1511 /* we have to move any children onto the real NULL
1513 struct talloc_chunk
*tc
, *tc2
;
1514 tc
= talloc_chunk_from_ptr(null_context
);
1515 for (tc2
= tc
->child
; tc2
; tc2
=tc2
->next
) {
1516 if (tc2
->parent
== tc
) tc2
->parent
= NULL
;
1517 if (tc2
->prev
== tc
) tc2
->prev
= NULL
;
1519 for (tc2
= tc
->next
; tc2
; tc2
=tc2
->next
) {
1520 if (tc2
->parent
== tc
) tc2
->parent
= NULL
;
1521 if (tc2
->prev
== tc
) tc2
->prev
= NULL
;
1526 talloc_free(null_context
);
1527 null_context
= NULL
;
1531 enable leak reporting on exit
1533 _PUBLIC_
void talloc_enable_leak_report(void)
1535 talloc_enable_null_tracking();
1536 atexit(talloc_report_null
);
1540 enable full leak reporting on exit
1542 _PUBLIC_
void talloc_enable_leak_report_full(void)
1544 talloc_enable_null_tracking();
1545 atexit(talloc_report_null_full
);
1549 talloc and zero memory.
1551 _PUBLIC_
void *_talloc_zero(const void *ctx
, size_t size
, const char *name
)
1553 void *p
= _talloc_named_const(ctx
, size
, name
);
1556 memset(p
, '\0', size
);
1563 memdup with a talloc.
1565 _PUBLIC_
void *_talloc_memdup(const void *t
, const void *p
, size_t size
, const char *name
)
1567 void *newp
= _talloc_named_const(t
, size
, name
);
1570 memcpy(newp
, p
, size
);
1576 static inline char *__talloc_strlendup(const void *t
, const char *p
, size_t len
)
1580 ret
= (char *)__talloc(t
, len
+ 1);
1581 if (unlikely(!ret
)) return NULL
;
1583 memcpy(ret
, p
, len
);
1586 _talloc_set_name_const(ret
, ret
);
1591 strdup with a talloc
1593 _PUBLIC_
char *talloc_strdup(const void *t
, const char *p
)
1595 if (unlikely(!p
)) return NULL
;
1596 return __talloc_strlendup(t
, p
, strlen(p
));
1600 strndup with a talloc
1602 _PUBLIC_
char *talloc_strndup(const void *t
, const char *p
, size_t n
)
1604 if (unlikely(!p
)) return NULL
;
1605 return __talloc_strlendup(t
, p
, strnlen(p
, n
));
1608 static inline char *__talloc_strlendup_append(char *s
, size_t slen
,
1609 const char *a
, size_t alen
)
1613 ret
= talloc_realloc(NULL
, s
, char, slen
+ alen
+ 1);
1614 if (unlikely(!ret
)) return NULL
;
1616 /* append the string and the trailing \0 */
1617 memcpy(&ret
[slen
], a
, alen
);
1620 _talloc_set_name_const(ret
, ret
);
1625 * Appends at the end of the string.
1627 _PUBLIC_
char *talloc_strdup_append(char *s
, const char *a
)
1630 return talloc_strdup(NULL
, a
);
1637 return __talloc_strlendup_append(s
, strlen(s
), a
, strlen(a
));
1641 * Appends at the end of the talloc'ed buffer,
1642 * not the end of the string.
1644 _PUBLIC_
char *talloc_strdup_append_buffer(char *s
, const char *a
)
1649 return talloc_strdup(NULL
, a
);
1656 slen
= talloc_get_size(s
);
1657 if (likely(slen
> 0)) {
1661 return __talloc_strlendup_append(s
, slen
, a
, strlen(a
));
1665 * Appends at the end of the string.
1667 _PUBLIC_
char *talloc_strndup_append(char *s
, const char *a
, size_t n
)
1670 return talloc_strdup(NULL
, a
);
1677 return __talloc_strlendup_append(s
, strlen(s
), a
, strnlen(a
, n
));
1681 * Appends at the end of the talloc'ed buffer,
1682 * not the end of the string.
1684 _PUBLIC_
char *talloc_strndup_append_buffer(char *s
, const char *a
, size_t n
)
1689 return talloc_strdup(NULL
, a
);
1696 slen
= talloc_get_size(s
);
1697 if (likely(slen
> 0)) {
1701 return __talloc_strlendup_append(s
, slen
, a
, strnlen(a
, n
));
1704 #ifndef HAVE_VA_COPY
1705 #ifdef HAVE___VA_COPY
1706 #define va_copy(dest, src) __va_copy(dest, src)
1708 #define va_copy(dest, src) (dest) = (src)
1712 _PUBLIC_
char *talloc_vasprintf(const void *t
, const char *fmt
, va_list ap
)
1719 /* this call looks strange, but it makes it work on older solaris boxes */
1721 len
= vsnprintf(&c
, 1, fmt
, ap2
);
1723 if (unlikely(len
< 0)) {
1727 ret
= (char *)__talloc(t
, len
+1);
1728 if (unlikely(!ret
)) return NULL
;
1731 vsnprintf(ret
, len
+1, fmt
, ap2
);
1734 _talloc_set_name_const(ret
, ret
);
1740 Perform string formatting, and return a pointer to newly allocated
1741 memory holding the result, inside a memory pool.
1743 _PUBLIC_
char *talloc_asprintf(const void *t
, const char *fmt
, ...)
1749 ret
= talloc_vasprintf(t
, fmt
, ap
);
1754 static inline char *__talloc_vaslenprintf_append(char *s
, size_t slen
,
1755 const char *fmt
, va_list ap
)
1756 PRINTF_ATTRIBUTE(3,0);
1758 static inline char *__talloc_vaslenprintf_append(char *s
, size_t slen
,
1759 const char *fmt
, va_list ap
)
1766 alen
= vsnprintf(&c
, 1, fmt
, ap2
);
1770 /* Either the vsnprintf failed or the format resulted in
1771 * no characters being formatted. In the former case, we
1772 * ought to return NULL, in the latter we ought to return
1773 * the original string. Most current callers of this
1774 * function expect it to never return NULL.
1779 s
= talloc_realloc(NULL
, s
, char, slen
+ alen
+ 1);
1780 if (!s
) return NULL
;
1783 vsnprintf(s
+ slen
, alen
+ 1, fmt
, ap2
);
1786 _talloc_set_name_const(s
, s
);
1791 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1792 * and return @p s, which may have moved. Good for gradually
1793 * accumulating output into a string buffer. Appends at the end
1796 _PUBLIC_
char *talloc_vasprintf_append(char *s
, const char *fmt
, va_list ap
)
1799 return talloc_vasprintf(NULL
, fmt
, ap
);
1802 return __talloc_vaslenprintf_append(s
, strlen(s
), fmt
, ap
);
1806 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1807 * and return @p s, which may have moved. Always appends at the
1808 * end of the talloc'ed buffer, not the end of the string.
1810 _PUBLIC_
char *talloc_vasprintf_append_buffer(char *s
, const char *fmt
, va_list ap
)
1815 return talloc_vasprintf(NULL
, fmt
, ap
);
1818 slen
= talloc_get_size(s
);
1819 if (likely(slen
> 0)) {
1823 return __talloc_vaslenprintf_append(s
, slen
, 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
1829 into a string buffer.
1831 _PUBLIC_
char *talloc_asprintf_append(char *s
, const char *fmt
, ...)
1836 s
= talloc_vasprintf_append(s
, fmt
, ap
);
1842 Realloc @p s to append the formatted result of @p fmt and return @p
1843 s, which may have moved. Good for gradually accumulating output
1846 _PUBLIC_
char *talloc_asprintf_append_buffer(char *s
, const char *fmt
, ...)
1851 s
= talloc_vasprintf_append_buffer(s
, fmt
, ap
);
1857 alloc an array, checking for integer overflow in the array size
1859 _PUBLIC_
void *_talloc_array(const void *ctx
, size_t el_size
, unsigned count
, const char *name
)
1861 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
1864 return _talloc_named_const(ctx
, el_size
* count
, name
);
1868 alloc an zero array, checking for integer overflow in the array size
1870 _PUBLIC_
void *_talloc_zero_array(const void *ctx
, size_t el_size
, unsigned count
, const char *name
)
1872 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
1875 return _talloc_zero(ctx
, el_size
* count
, name
);
1879 realloc an array, checking for integer overflow in the array size
1881 _PUBLIC_
void *_talloc_realloc_array(const void *ctx
, void *ptr
, size_t el_size
, unsigned count
, const char *name
)
1883 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
1886 return _talloc_realloc(ctx
, ptr
, el_size
* count
, name
);
1890 a function version of talloc_realloc(), so it can be passed as a function pointer
1891 to libraries that want a realloc function (a realloc function encapsulates
1892 all the basic capabilities of an allocation library, which is why this is useful)
1894 _PUBLIC_
void *talloc_realloc_fn(const void *context
, void *ptr
, size_t size
)
1896 return _talloc_realloc(context
, ptr
, size
, NULL
);
1900 static int talloc_autofree_destructor(void *ptr
)
1902 autofree_context
= NULL
;
1906 static void talloc_autofree(void)
1908 talloc_free(autofree_context
);
1912 return a context which will be auto-freed on exit
1913 this is useful for reducing the noise in leak reports
1915 _PUBLIC_
void *talloc_autofree_context(void)
1917 if (autofree_context
== NULL
) {
1918 autofree_context
= _talloc_named_const(NULL
, 0, "autofree_context");
1919 talloc_set_destructor(autofree_context
, talloc_autofree_destructor
);
1920 atexit(talloc_autofree
);
1922 return autofree_context
;
1925 _PUBLIC_
size_t talloc_get_size(const void *context
)
1927 struct talloc_chunk
*tc
;
1929 if (context
== NULL
) {
1930 context
= null_context
;
1932 if (context
== NULL
) {
1936 tc
= talloc_chunk_from_ptr(context
);
1942 find a parent of this context that has the given name, if any
1944 _PUBLIC_
void *talloc_find_parent_byname(const void *context
, const char *name
)
1946 struct talloc_chunk
*tc
;
1948 if (context
== NULL
) {
1952 tc
= talloc_chunk_from_ptr(context
);
1954 if (tc
->name
&& strcmp(tc
->name
, name
) == 0) {
1955 return TC_PTR_FROM_CHUNK(tc
);
1957 while (tc
&& tc
->prev
) tc
= tc
->prev
;
1966 show the parentage of a context
1968 _PUBLIC_
void talloc_show_parents(const void *context
, FILE *file
)
1970 struct talloc_chunk
*tc
;
1972 if (context
== NULL
) {
1973 fprintf(file
, "talloc no parents for NULL\n");
1977 tc
= talloc_chunk_from_ptr(context
);
1978 fprintf(file
, "talloc parents of '%s'\n", talloc_get_name(context
));
1980 fprintf(file
, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc
)));
1981 while (tc
&& tc
->prev
) tc
= tc
->prev
;
1990 return 1 if ptr is a parent of context
1992 static int _talloc_is_parent(const void *context
, const void *ptr
, int depth
)
1994 struct talloc_chunk
*tc
;
1996 if (context
== NULL
) {
2000 tc
= talloc_chunk_from_ptr(context
);
2001 while (tc
&& depth
> 0) {
2002 if (TC_PTR_FROM_CHUNK(tc
) == ptr
) return 1;
2003 while (tc
&& tc
->prev
) tc
= tc
->prev
;
2013 return 1 if ptr is a parent of context
2015 _PUBLIC_
int talloc_is_parent(const void *context
, const void *ptr
)
2017 return _talloc_is_parent(context
, ptr
, TALLOC_MAX_DEPTH
);