s3: don't build krb5 locator plugin if we don't build winbind
[Samba/gebeck_regimport.git] / lib / talloc / talloc.c
blobcafe4d6e7a63c20653c8e3b50e4828b4823dedb4
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 _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, ...)
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 _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",
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 _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;
301 find parents name
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
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 _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)) {
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 _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))) {
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 _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);
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 if this is a reference from a child or
575 * grandchild back to it's parent or grandparent
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 _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)) {
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 #if 0
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);
764 #endif
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)) {
782 return 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) {
793 return NULL;
795 return discard_const_p(void, ptr);
799 /* it wasn't a parent */
800 return NULL;
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);
819 if (p == NULL) {
820 if (context == NULL) break;
821 } else if (TC_PTR_FROM_CHUNK(p) == context) {
822 break;
825 if (h == NULL) {
826 return -1;
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;
839 void *new_parent;
841 if (ptr == NULL) {
842 return -1;
845 if (context == NULL) {
846 context = null_context;
849 if (talloc_unreference(context, ptr) == 0) {
850 return 0;
853 if (context == NULL) {
854 if (talloc_parent_chunk(ptr) != NULL) {
855 return -1;
857 } else {
858 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
859 return -1;
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);
870 if (new_p) {
871 new_parent = TC_PTR_FROM_CHUNK(new_p);
872 } else {
873 new_parent = NULL;
876 if (talloc_unreference(new_parent, ptr) != 0) {
877 return -1;
880 _talloc_steal_internal(new_parent, ptr);
882 return 0;
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");
897 return tc->name;
901 add a name to an existing pointer
903 _PUBLIC_ const char *talloc_set_name(const void *ptr, const char *fmt, ...)
905 const char *name;
906 va_list ap;
907 va_start(ap, fmt);
908 name = talloc_set_name_v(ptr, fmt, ap);
909 va_end(ap);
910 return name;
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
917 to name the pointer.
919 _PUBLIC_ void *talloc_named(const void *context, size_t size, const char *fmt, ...)
921 va_list ap;
922 void *ptr;
923 const char *name;
925 ptr = __talloc(context, size);
926 if (unlikely(ptr == NULL)) return NULL;
928 va_start(ap, fmt);
929 name = talloc_set_name_v(ptr, fmt, ap);
930 va_end(ap);
932 if (unlikely(name == NULL)) {
933 _talloc_free_internal(ptr, __location__);
934 return NULL;
937 return ptr;
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)) {
947 return ".reference";
949 if (likely(tc->name)) {
950 return tc->name;
952 return "UNNAMED";
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)
962 const char *pname;
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);
968 return NULL;
971 static void talloc_abort_type_missmatch(const char *location,
972 const char *name,
973 const char *expected)
975 const char *reason;
977 reason = talloc_asprintf(NULL,
978 "%s: Type mismatch: name[%s] expected[%s]",
979 location,
980 name?name:"NULL",
981 expected);
982 if (!reason) {
983 reason = "Type mismatch";
986 talloc_abort(reason);
989 _PUBLIC_ void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location)
991 const char *pname;
993 if (unlikely(ptr == NULL)) {
994 talloc_abort_type_missmatch(location, NULL, name);
995 return NULL;
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);
1004 return NULL;
1008 this is for compatibility with older versions of talloc
1010 _PUBLIC_ void *talloc_init(const char *fmt, ...)
1012 va_list ap;
1013 void *ptr;
1014 const char *name;
1017 * samba3 expects talloc_report_depth_cb(NULL, ...)
1018 * reports all talloc'ed memory, so we need to enable
1019 * null_tracking
1021 talloc_enable_null_tracking();
1023 ptr = __talloc(NULL, 0);
1024 if (unlikely(ptr == NULL)) return NULL;
1026 va_start(ap, fmt);
1027 name = talloc_set_name_v(ptr, fmt, ap);
1028 va_end(ap);
1030 if (unlikely(name == NULL)) {
1031 _talloc_free_internal(ptr, __location__);
1032 return NULL;
1035 return ptr;
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)) {
1048 return;
1051 tc = talloc_chunk_from_ptr(ptr);
1053 while (tc->child) {
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);
1080 #endif
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
1112 pointer recursively
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)) {
1123 return -1;
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
1134 one parent */
1135 return talloc_unlink(null_context, ptr);
1138 talloc_log("ERROR: talloc_free with references at %s\n",
1139 location);
1141 for (h=tc->refs; h; h=h->next) {
1142 talloc_log("\treference at %s\n",
1143 h->location);
1145 return -1;
1148 return _talloc_free_internal(ptr, location);
1154 A talloc version of realloc. The context argument is only used if
1155 ptr is NULL
1157 _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
1159 struct talloc_chunk *tc;
1160 void *new_ptr;
1161 bool malloced = false;
1163 /* size zero is equivalent to free() */
1164 if (unlikely(size == 0)) {
1165 talloc_unlink(context, ptr);
1166 return NULL;
1169 if (unlikely(size >= MAX_TALLOC_SIZE)) {
1170 return NULL;
1173 /* realloc(NULL) is equivalent to malloc() */
1174 if (ptr == NULL) {
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)) {
1182 return NULL;
1185 /* don't let anybody try to realloc a talloc_pool */
1186 if (unlikely(tc->flags & TALLOC_FLAG_POOL)) {
1187 return NULL;
1190 /* don't shrink if we have less than 1k to gain */
1191 if ((size < tc->size) && ((tc->size - size) < 1024)) {
1192 tc->size = size;
1193 return ptr;
1196 /* by resetting magic we catch users of the old memory */
1197 tc->flags |= TALLOC_FLAG_FREE;
1199 #if ALWAYS_REALLOC
1200 new_ptr = malloc(size + TC_HDR_SIZE);
1201 if (new_ptr) {
1202 memcpy(new_ptr, tc, MIN(tc->size, size) + TC_HDR_SIZE);
1203 free(tc);
1205 #else
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 *)
1210 (tc->pool)) -= 1;
1212 if (new_ptr == NULL) {
1213 new_ptr = malloc(TC_HDR_SIZE+size);
1214 malloced = true;
1217 if (new_ptr) {
1218 memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
1221 else {
1222 new_ptr = realloc(tc, size + TC_HDR_SIZE);
1224 #endif
1225 if (unlikely(!new_ptr)) {
1226 tc->flags &= ~TALLOC_FLAG_FREE;
1227 return NULL;
1230 tc = (struct talloc_chunk *)new_ptr;
1231 tc->flags &= ~TALLOC_FLAG_FREE;
1232 if (malloced) {
1233 tc->flags &= ~TALLOC_FLAG_POOLMEM;
1235 if (tc->parent) {
1236 tc->parent->child = tc;
1238 if (tc->child) {
1239 tc->child->parent = tc;
1242 if (tc->prev) {
1243 tc->prev->next = tc;
1245 if (tc->next) {
1246 tc->next->prev = tc;
1249 tc->size = size;
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));
1263 (*pptr) = NULL;
1264 return ret;
1268 return the total size of a talloc pool (subtree)
1270 _PUBLIC_ size_t talloc_total_size(const void *ptr)
1272 size_t total = 0;
1273 struct talloc_chunk *c, *tc;
1275 if (ptr == NULL) {
1276 ptr = null_context;
1278 if (ptr == NULL) {
1279 return 0;
1282 tc = talloc_chunk_from_ptr(ptr);
1284 if (tc->flags & TALLOC_FLAG_LOOP) {
1285 return 0;
1288 tc->flags |= TALLOC_FLAG_LOOP;
1290 if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) {
1291 total = tc->size;
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;
1299 return total;
1303 return the total number of blocks in a talloc pool (subtree)
1305 _PUBLIC_ size_t talloc_total_blocks(const void *ptr)
1307 size_t total = 0;
1308 struct talloc_chunk *c, *tc;
1310 if (ptr == NULL) {
1311 ptr = null_context;
1313 if (ptr == NULL) {
1314 return 0;
1317 tc = talloc_chunk_from_ptr(ptr);
1319 if (tc->flags & TALLOC_FLAG_LOOP) {
1320 return 0;
1323 tc->flags |= TALLOC_FLAG_LOOP;
1325 total++;
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;
1332 return total;
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;
1342 size_t ret = 0;
1344 for (h=tc->refs;h;h=h->next) {
1345 ret++;
1347 return ret;
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,
1356 int is_ref,
1357 void *private_data),
1358 void *private_data)
1360 struct talloc_chunk *c, *tc;
1362 if (ptr == NULL) {
1363 ptr = null_context;
1365 if (ptr == NULL) return;
1367 tc = talloc_chunk_from_ptr(ptr);
1369 if (tc->flags & TALLOC_FLAG_LOOP) {
1370 return;
1373 callback(ptr, depth, max_depth, 0, private_data);
1375 if (max_depth >= 0 && depth >= max_depth) {
1376 return;
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);
1384 } else {
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;
1396 if (is_ref) {
1397 fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
1398 return;
1401 if (depth == 0) {
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));
1406 return;
1409 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
1410 depth*4, "",
1411 name,
1412 (unsigned long)talloc_total_size(ptr),
1413 (unsigned long)talloc_total_blocks(ptr),
1414 (int)talloc_reference_count(ptr), ptr);
1416 #if 0
1417 fprintf(f, "content: ");
1418 if (talloc_total_size(ptr)) {
1419 int tot = talloc_total_size(ptr);
1420 int i;
1422 for (i = 0; i < tot; i++) {
1423 if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
1424 fprintf(f, "%c", ((char *)ptr)[i]);
1425 } else {
1426 fprintf(f, "~%02x", ((char *)ptr)[i]);
1430 fprintf(f, "\n");
1431 #endif
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)
1439 if (f) {
1440 talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
1441 fflush(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
1512 context */
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;
1523 tc->child = NULL;
1524 tc->next = 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);
1555 if (p) {
1556 memset(p, '\0', size);
1559 return p;
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);
1569 if (likely(newp)) {
1570 memcpy(newp, p, size);
1573 return newp;
1576 static inline char *__talloc_strlendup(const void *t, const char *p, size_t len)
1578 char *ret;
1580 ret = (char *)__talloc(t, len + 1);
1581 if (unlikely(!ret)) return NULL;
1583 memcpy(ret, p, len);
1584 ret[len] = 0;
1586 _talloc_set_name_const(ret, ret);
1587 return 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)
1611 char *ret;
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);
1618 ret[slen+alen] = 0;
1620 _talloc_set_name_const(ret, ret);
1621 return ret;
1625 * Appends at the end of the string.
1627 _PUBLIC_ char *talloc_strdup_append(char *s, const char *a)
1629 if (unlikely(!s)) {
1630 return talloc_strdup(NULL, a);
1633 if (unlikely(!a)) {
1634 return s;
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)
1646 size_t slen;
1648 if (unlikely(!s)) {
1649 return talloc_strdup(NULL, a);
1652 if (unlikely(!a)) {
1653 return s;
1656 slen = talloc_get_size(s);
1657 if (likely(slen > 0)) {
1658 slen--;
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)
1669 if (unlikely(!s)) {
1670 return talloc_strdup(NULL, a);
1673 if (unlikely(!a)) {
1674 return s;
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)
1686 size_t slen;
1688 if (unlikely(!s)) {
1689 return talloc_strdup(NULL, a);
1692 if (unlikely(!a)) {
1693 return s;
1696 slen = talloc_get_size(s);
1697 if (likely(slen > 0)) {
1698 slen--;
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)
1707 #else
1708 #define va_copy(dest, src) (dest) = (src)
1709 #endif
1710 #endif
1712 _PUBLIC_ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1714 int len;
1715 char *ret;
1716 va_list ap2;
1717 char c;
1719 /* this call looks strange, but it makes it work on older solaris boxes */
1720 va_copy(ap2, ap);
1721 len = vsnprintf(&c, 1, fmt, ap2);
1722 va_end(ap2);
1723 if (unlikely(len < 0)) {
1724 return NULL;
1727 ret = (char *)__talloc(t, len+1);
1728 if (unlikely(!ret)) return NULL;
1730 va_copy(ap2, ap);
1731 vsnprintf(ret, len+1, fmt, ap2);
1732 va_end(ap2);
1734 _talloc_set_name_const(ret, ret);
1735 return 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, ...)
1745 va_list ap;
1746 char *ret;
1748 va_start(ap, fmt);
1749 ret = talloc_vasprintf(t, fmt, ap);
1750 va_end(ap);
1751 return ret;
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)
1761 ssize_t alen;
1762 va_list ap2;
1763 char c;
1765 va_copy(ap2, ap);
1766 alen = vsnprintf(&c, 1, fmt, ap2);
1767 va_end(ap2);
1769 if (alen <= 0) {
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.
1776 return s;
1779 s = talloc_realloc(NULL, s, char, slen + alen + 1);
1780 if (!s) return NULL;
1782 va_copy(ap2, ap);
1783 vsnprintf(s + slen, alen + 1, fmt, ap2);
1784 va_end(ap2);
1786 _talloc_set_name_const(s, s);
1787 return 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
1794 * of the string.
1796 _PUBLIC_ char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1798 if (unlikely(!s)) {
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)
1812 size_t slen;
1814 if (unlikely(!s)) {
1815 return talloc_vasprintf(NULL, fmt, ap);
1818 slen = talloc_get_size(s);
1819 if (likely(slen > 0)) {
1820 slen--;
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, ...)
1833 va_list ap;
1835 va_start(ap, fmt);
1836 s = talloc_vasprintf_append(s, fmt, ap);
1837 va_end(ap);
1838 return s;
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
1844 into a buffer.
1846 _PUBLIC_ char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...)
1848 va_list ap;
1850 va_start(ap, fmt);
1851 s = talloc_vasprintf_append_buffer(s, fmt, ap);
1852 va_end(ap);
1853 return s;
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) {
1862 return NULL;
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) {
1873 return NULL;
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) {
1884 return NULL;
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;
1903 return 0;
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) {
1933 return 0;
1936 tc = talloc_chunk_from_ptr(context);
1938 return tc->size;
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) {
1949 return NULL;
1952 tc = talloc_chunk_from_ptr(context);
1953 while (tc) {
1954 if (tc->name && strcmp(tc->name, name) == 0) {
1955 return TC_PTR_FROM_CHUNK(tc);
1957 while (tc && tc->prev) tc = tc->prev;
1958 if (tc) {
1959 tc = tc->parent;
1962 return NULL;
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");
1974 return;
1977 tc = talloc_chunk_from_ptr(context);
1978 fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
1979 while (tc) {
1980 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
1981 while (tc && tc->prev) tc = tc->prev;
1982 if (tc) {
1983 tc = tc->parent;
1986 fflush(file);
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) {
1997 return 0;
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;
2004 if (tc) {
2005 tc = tc->parent;
2006 depth--;
2009 return 0;
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);