ir_to_mesa: Support texture rectangle targets
[mesa/nouveau-pmpeg.git] / src / talloc / talloc.c
blobcc01346a7f0d24a1c8620894a2e9383bf23f7714
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 "talloc.h"
34 #include <string.h>
36 #define TALLOC_MIN(a,b) ((a)<(b)?(a):(b))
38 /* Visual C++ 2008 compatibility */
39 #if defined(_MSC_VER) && !defined(_cplusplus)
40 typedef size_t ssize_t;
41 #define inline __inline
42 #endif
44 /* Xcode/gcc4.0 compatibility */
45 #if defined(__APPLE__) || defined(__MINGW32__)
46 static size_t strnlen (const char* s, size_t n)
48 size_t i;
49 for (i = 0; i < n; ++i)
51 if (s[i] == '\0')
52 break;
54 return i;
56 #endif
58 /* Visual C++ 2008 & Xcode/gcc4.0 compatibility */
59 #if !defined(_cplusplus) && (defined(WIN32) || defined(__APPLE__))
60 typedef int bool;
61 #define false 0
62 #define true 1
63 #endif
66 #ifdef TALLOC_BUILD_VERSION_MAJOR
67 #if (TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR)
68 #error "TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR"
69 #endif
70 #endif
72 #ifdef TALLOC_BUILD_VERSION_MINOR
73 #if (TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR)
74 #error "TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR"
75 #endif
76 #endif
78 /* use this to force every realloc to change the pointer, to stress test
79 code that might not cope */
80 #define ALWAYS_REALLOC 0
83 #define MAX_TALLOC_SIZE 0x10000000
84 #define TALLOC_MAGIC_BASE 0xe814ec70
85 #define TALLOC_MAGIC ( \
86 TALLOC_MAGIC_BASE + \
87 (TALLOC_VERSION_MAJOR << 12) + \
88 (TALLOC_VERSION_MINOR << 4) \
91 #define TALLOC_FLAG_FREE 0x01
92 #define TALLOC_FLAG_LOOP 0x02
93 #define TALLOC_FLAG_POOL 0x04 /* This is a talloc pool */
94 #define TALLOC_FLAG_POOLMEM 0x08 /* This is allocated in a pool */
95 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
97 /* by default we abort when given a bad pointer (such as when talloc_free() is called
98 on a pointer that came from malloc() */
99 #ifndef TALLOC_ABORT
100 #define TALLOC_ABORT(reason) abort()
101 #endif
103 #ifndef discard_const_p
104 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
105 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
106 #else
107 # define discard_const_p(type, ptr) ((type *)(ptr))
108 #endif
109 #endif
111 /* these macros gain us a few percent of speed on gcc */
112 #if (__GNUC__ >= 3)
113 /* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
114 as its first argument */
115 #ifndef likely
116 #define likely(x) __builtin_expect(!!(x), 1)
117 #endif
118 #ifndef unlikely
119 #define unlikely(x) __builtin_expect(!!(x), 0)
120 #endif
121 #else
122 #ifndef likely
123 #define likely(x) (x)
124 #endif
125 #ifndef unlikely
126 #define unlikely(x) (x)
127 #endif
128 #endif
130 /* this null_context is only used if talloc_enable_leak_report() or
131 talloc_enable_leak_report_full() is called, otherwise it remains
132 NULL
134 static void *null_context;
135 static void *autofree_context;
137 struct talloc_reference_handle {
138 struct talloc_reference_handle *next, *prev;
139 void *ptr;
140 const char *location;
143 typedef int (*talloc_destructor_t)(void *);
145 struct talloc_chunk {
146 struct talloc_chunk *next, *prev;
147 struct talloc_chunk *parent, *child;
148 struct talloc_reference_handle *refs;
149 talloc_destructor_t destructor;
150 const char *name;
151 size_t size;
152 unsigned flags;
155 * "pool" has dual use:
157 * For the talloc pool itself (i.e. TALLOC_FLAG_POOL is set), "pool"
158 * marks the end of the currently allocated area.
160 * For members of the pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool"
161 * is a pointer to the struct talloc_chunk of the pool that it was
162 * allocated from. This way children can quickly find the pool to chew
163 * from.
165 void *pool;
168 /* 16 byte alignment seems to keep everyone happy */
169 #define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
170 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
172 int talloc_version_major(void)
174 return TALLOC_VERSION_MAJOR;
177 int talloc_version_minor(void)
179 return TALLOC_VERSION_MINOR;
182 static void (*talloc_log_fn)(const char *message);
184 void talloc_set_log_fn(void (*log_fn)(const char *message))
186 talloc_log_fn = log_fn;
189 static void talloc_log(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
190 static void talloc_log(const char *fmt, ...)
192 va_list ap;
193 char *message;
195 if (!talloc_log_fn) {
196 return;
199 va_start(ap, fmt);
200 message = talloc_vasprintf(NULL, fmt, ap);
201 va_end(ap);
203 talloc_log_fn(message);
204 talloc_free(message);
207 static void talloc_log_stderr(const char *message)
209 fprintf(stderr, "%s", message);
212 void talloc_set_log_stderr(void)
214 talloc_set_log_fn(talloc_log_stderr);
217 static void (*talloc_abort_fn)(const char *reason);
219 void talloc_set_abort_fn(void (*abort_fn)(const char *reason))
221 talloc_abort_fn = abort_fn;
224 static void talloc_abort(const char *reason)
226 talloc_log("%s\n", reason);
228 if (!talloc_abort_fn) {
229 TALLOC_ABORT(reason);
232 talloc_abort_fn(reason);
235 static void talloc_abort_magic(unsigned magic)
237 unsigned striped = magic - TALLOC_MAGIC_BASE;
238 unsigned major = (striped & 0xFFFFF000) >> 12;
239 unsigned minor = (striped & 0x00000FF0) >> 4;
240 talloc_log("Bad talloc magic[0x%08X/%u/%u] expected[0x%08X/%u/%u]\n",
241 magic, major, minor,
242 TALLOC_MAGIC, TALLOC_VERSION_MAJOR, TALLOC_VERSION_MINOR);
243 talloc_abort("Bad talloc magic value - wrong talloc version used/mixed");
246 static void talloc_abort_double_free(void)
248 talloc_abort("Bad talloc magic value - double free");
251 static void talloc_abort_unknown_value(void)
253 talloc_abort("Bad talloc magic value - unknown value");
256 /* panic if we get a bad magic value */
257 static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
259 const char *pp = (const char *)ptr;
260 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
261 if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) {
262 if ((tc->flags & (~0xFFF)) == TALLOC_MAGIC_BASE) {
263 talloc_abort_magic(tc->flags & (~0xF));
264 return NULL;
267 if (tc->flags & TALLOC_FLAG_FREE) {
268 talloc_log("talloc: double free error - first free may be at %s\n", tc->name);
269 talloc_abort_double_free();
270 return NULL;
271 } else {
272 talloc_abort_unknown_value();
273 return NULL;
276 return tc;
279 /* hook into the front of the list */
280 #define _TLIST_ADD(list, p) \
281 do { \
282 if (!(list)) { \
283 (list) = (p); \
284 (p)->next = (p)->prev = NULL; \
285 } else { \
286 (list)->prev = (p); \
287 (p)->next = (list); \
288 (p)->prev = NULL; \
289 (list) = (p); \
291 } while (0)
293 /* remove an element from a list - element doesn't have to be in list. */
294 #define _TLIST_REMOVE(list, p) \
295 do { \
296 if ((p) == (list)) { \
297 (list) = (p)->next; \
298 if (list) (list)->prev = NULL; \
299 } else { \
300 if ((p)->prev) (p)->prev->next = (p)->next; \
301 if ((p)->next) (p)->next->prev = (p)->prev; \
303 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
304 } while (0)
308 return the parent chunk of a pointer
310 static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr)
312 struct talloc_chunk *tc;
314 if (unlikely(ptr == NULL)) {
315 return NULL;
318 tc = talloc_chunk_from_ptr(ptr);
319 while (tc->prev) tc=tc->prev;
321 return tc->parent;
324 void *talloc_parent(const void *ptr)
326 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
327 return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
331 find parents name
333 const char *talloc_parent_name(const void *ptr)
335 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
336 return tc? tc->name : NULL;
340 A pool carries an in-pool object count count in the first 16 bytes.
341 bytes. This is done to support talloc_steal() to a parent outside of the
342 pool. The count includes the pool itself, so a talloc_free() on a pool will
343 only destroy the pool if the count has dropped to zero. A talloc_free() of a
344 pool member will reduce the count, and eventually also call free(3) on the
345 pool memory.
347 The object count is not put into "struct talloc_chunk" because it is only
348 relevant for talloc pools and the alignment to 16 bytes would increase the
349 memory footprint of each talloc chunk by those 16 bytes.
352 #define TALLOC_POOL_HDR_SIZE 16
354 static unsigned int *talloc_pool_objectcount(struct talloc_chunk *tc)
356 return (unsigned int *)((char *)tc + sizeof(struct talloc_chunk));
360 Allocate from a pool
363 static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,
364 size_t size)
366 struct talloc_chunk *pool_ctx = NULL;
367 size_t space_left;
368 struct talloc_chunk *result;
369 size_t chunk_size;
371 if (parent == NULL) {
372 return NULL;
375 if (parent->flags & TALLOC_FLAG_POOL) {
376 pool_ctx = parent;
378 else if (parent->flags & TALLOC_FLAG_POOLMEM) {
379 pool_ctx = (struct talloc_chunk *)parent->pool;
382 if (pool_ctx == NULL) {
383 return NULL;
386 space_left = ((char *)pool_ctx + TC_HDR_SIZE + pool_ctx->size)
387 - ((char *)pool_ctx->pool);
390 * Align size to 16 bytes
392 chunk_size = ((size + 15) & ~15);
394 if (space_left < chunk_size) {
395 return NULL;
398 result = (struct talloc_chunk *)pool_ctx->pool;
400 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
401 VALGRIND_MAKE_MEM_UNDEFINED(result, size);
402 #endif
404 pool_ctx->pool = (void *)((char *)result + chunk_size);
406 result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM;
407 result->pool = pool_ctx;
409 *talloc_pool_objectcount(pool_ctx) += 1;
411 return result;
415 Allocate a bit of memory as a child of an existing pointer
417 static inline void *__talloc(const void *context, size_t size)
419 struct talloc_chunk *tc = NULL;
421 if (unlikely(context == NULL)) {
422 context = null_context;
425 if (unlikely(size >= MAX_TALLOC_SIZE)) {
426 return NULL;
429 if (context != NULL) {
430 tc = talloc_alloc_pool(talloc_chunk_from_ptr(context),
431 TC_HDR_SIZE+size);
434 if (tc == NULL) {
435 tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size);
436 if (unlikely(tc == NULL)) return NULL;
437 tc->flags = TALLOC_MAGIC;
438 tc->pool = NULL;
441 tc->size = size;
442 tc->destructor = NULL;
443 tc->child = NULL;
444 tc->name = NULL;
445 tc->refs = NULL;
447 if (likely(context)) {
448 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
450 if (parent->child) {
451 parent->child->parent = NULL;
452 tc->next = parent->child;
453 tc->next->prev = tc;
454 } else {
455 tc->next = NULL;
457 tc->parent = parent;
458 tc->prev = NULL;
459 parent->child = tc;
460 } else {
461 tc->next = tc->prev = tc->parent = NULL;
464 return TC_PTR_FROM_CHUNK(tc);
468 * Create a talloc pool
471 void *talloc_pool(const void *context, size_t size)
473 void *result = __talloc(context, size + TALLOC_POOL_HDR_SIZE);
474 struct talloc_chunk *tc;
476 if (unlikely(result == NULL)) {
477 return NULL;
480 tc = talloc_chunk_from_ptr(result);
482 tc->flags |= TALLOC_FLAG_POOL;
483 tc->pool = (char *)result + TALLOC_POOL_HDR_SIZE;
485 *talloc_pool_objectcount(tc) = 1;
487 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
488 VALGRIND_MAKE_MEM_NOACCESS(tc->pool, size);
489 #endif
491 return result;
495 setup a destructor to be called on free of a pointer
496 the destructor should return 0 on success, or -1 on failure.
497 if the destructor fails then the free is failed, and the memory can
498 be continued to be used
500 void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
502 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
503 tc->destructor = destructor;
507 increase the reference count on a piece of memory.
509 int talloc_increase_ref_count(const void *ptr)
511 if (unlikely(!talloc_reference(null_context, ptr))) {
512 return -1;
514 return 0;
518 helper for talloc_reference()
520 this is referenced by a function pointer and should not be inline
522 static int talloc_reference_destructor(struct talloc_reference_handle *handle)
524 struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
525 _TLIST_REMOVE(ptr_tc->refs, handle);
526 return 0;
530 more efficient way to add a name to a pointer - the name must point to a
531 true string constant
533 static inline void _talloc_set_name_const(const void *ptr, const char *name)
535 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
536 tc->name = name;
540 internal talloc_named_const()
542 static inline void *_talloc_named_const(const void *context, size_t size, const char *name)
544 void *ptr;
546 ptr = __talloc(context, size);
547 if (unlikely(ptr == NULL)) {
548 return NULL;
551 _talloc_set_name_const(ptr, name);
553 return ptr;
557 make a secondary reference to a pointer, hanging off the given context.
558 the pointer remains valid until both the original caller and this given
559 context are freed.
561 the major use for this is when two different structures need to reference the
562 same underlying data, and you want to be able to free the two instances separately,
563 and in either order
565 void *_talloc_reference_loc(const void *context, const void *ptr, const char *location)
567 struct talloc_chunk *tc;
568 struct talloc_reference_handle *handle;
569 if (unlikely(ptr == NULL)) return NULL;
571 tc = talloc_chunk_from_ptr(ptr);
572 handle = (struct talloc_reference_handle *)_talloc_named_const(context,
573 sizeof(struct talloc_reference_handle),
574 TALLOC_MAGIC_REFERENCE);
575 if (unlikely(handle == NULL)) return NULL;
577 /* note that we hang the destructor off the handle, not the
578 main context as that allows the caller to still setup their
579 own destructor on the context if they want to */
580 talloc_set_destructor(handle, talloc_reference_destructor);
581 handle->ptr = discard_const_p(void, ptr);
582 handle->location = location;
583 _TLIST_ADD(tc->refs, handle);
584 return handle->ptr;
587 static void *_talloc_steal_internal(const void *new_ctx, const void *ptr);
590 internal talloc_free call
592 static inline int _talloc_free_internal(void *ptr, const char *location)
594 struct talloc_chunk *tc;
596 if (unlikely(ptr == NULL)) {
597 return -1;
600 tc = talloc_chunk_from_ptr(ptr);
602 if (unlikely(tc->refs)) {
603 int is_child;
604 /* check this is a reference from a child or grantchild
605 * back to it's parent or grantparent
607 * in that case we need to remove the reference and
608 * call another instance of talloc_free() on the current
609 * pointer.
611 is_child = talloc_is_parent(tc->refs, ptr);
612 _talloc_free_internal(tc->refs, location);
613 if (is_child) {
614 return _talloc_free_internal(ptr, location);
616 return -1;
619 if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) {
620 /* we have a free loop - stop looping */
621 return 0;
624 if (unlikely(tc->destructor)) {
625 talloc_destructor_t d = tc->destructor;
626 if (d == (talloc_destructor_t)-1) {
627 return -1;
629 tc->destructor = (talloc_destructor_t)-1;
630 if (d(ptr) == -1) {
631 tc->destructor = d;
632 return -1;
634 tc->destructor = NULL;
637 if (tc->parent) {
638 _TLIST_REMOVE(tc->parent->child, tc);
639 if (tc->parent->child) {
640 tc->parent->child->parent = tc->parent;
642 } else {
643 if (tc->prev) tc->prev->next = tc->next;
644 if (tc->next) tc->next->prev = tc->prev;
647 tc->flags |= TALLOC_FLAG_LOOP;
649 while (tc->child) {
650 /* we need to work out who will own an abandoned child
651 if it cannot be freed. In priority order, the first
652 choice is owner of any remaining reference to this
653 pointer, the second choice is our parent, and the
654 final choice is the null context. */
655 void *child = TC_PTR_FROM_CHUNK(tc->child);
656 const void *new_parent = null_context;
657 if (unlikely(tc->child->refs)) {
658 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
659 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
661 if (unlikely(_talloc_free_internal(child, location) == -1)) {
662 if (new_parent == null_context) {
663 struct talloc_chunk *p = talloc_parent_chunk(ptr);
664 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
666 _talloc_steal_internal(new_parent, child);
670 tc->flags |= TALLOC_FLAG_FREE;
672 /* we mark the freed memory with where we called the free
673 * from. This means on a double free error we can report where
674 * the first free came from
676 tc->name = location;
678 if (tc->flags & (TALLOC_FLAG_POOL|TALLOC_FLAG_POOLMEM)) {
679 struct talloc_chunk *pool;
680 unsigned int *pool_object_count;
682 pool = (tc->flags & TALLOC_FLAG_POOL)
683 ? tc : (struct talloc_chunk *)tc->pool;
685 pool_object_count = talloc_pool_objectcount(pool);
687 if (*pool_object_count == 0) {
688 talloc_abort("Pool object count zero!");
689 return 0;
692 *pool_object_count -= 1;
694 if (*pool_object_count == 0) {
695 free(pool);
698 else {
699 free(tc);
701 return 0;
705 move a lump of memory from one talloc context to another return the
706 ptr on success, or NULL if it could not be transferred.
707 passing NULL as ptr will always return NULL with no side effects.
709 static void *_talloc_steal_internal(const void *new_ctx, const void *ptr)
711 struct talloc_chunk *tc, *new_tc;
713 if (unlikely(!ptr)) {
714 return NULL;
717 if (unlikely(new_ctx == NULL)) {
718 new_ctx = null_context;
721 tc = talloc_chunk_from_ptr(ptr);
723 if (unlikely(new_ctx == NULL)) {
724 if (tc->parent) {
725 _TLIST_REMOVE(tc->parent->child, tc);
726 if (tc->parent->child) {
727 tc->parent->child->parent = tc->parent;
729 } else {
730 if (tc->prev) tc->prev->next = tc->next;
731 if (tc->next) tc->next->prev = tc->prev;
734 tc->parent = tc->next = tc->prev = NULL;
735 return discard_const_p(void, ptr);
738 new_tc = talloc_chunk_from_ptr(new_ctx);
740 if (unlikely(tc == new_tc || tc->parent == new_tc)) {
741 return discard_const_p(void, ptr);
744 if (tc->parent) {
745 _TLIST_REMOVE(tc->parent->child, tc);
746 if (tc->parent->child) {
747 tc->parent->child->parent = tc->parent;
749 } else {
750 if (tc->prev) tc->prev->next = tc->next;
751 if (tc->next) tc->next->prev = tc->prev;
754 tc->parent = new_tc;
755 if (new_tc->child) new_tc->child->parent = NULL;
756 _TLIST_ADD(new_tc->child, tc);
758 return discard_const_p(void, ptr);
762 move a lump of memory from one talloc context to another return the
763 ptr on success, or NULL if it could not be transferred.
764 passing NULL as ptr will always return NULL with no side effects.
766 void *_talloc_steal_loc(const void *new_ctx, const void *ptr, const char *location)
768 struct talloc_chunk *tc;
770 if (unlikely(ptr == NULL)) {
771 return NULL;
774 tc = talloc_chunk_from_ptr(ptr);
776 if (unlikely(tc->refs != NULL) && talloc_parent(ptr) != new_ctx) {
777 struct talloc_reference_handle *h;
779 talloc_log("WARNING: talloc_steal with references at %s\n",
780 location);
782 for (h=tc->refs; h; h=h->next) {
783 talloc_log("\treference at %s\n",
784 h->location);
788 return _talloc_steal_internal(new_ctx, ptr);
792 this is like a talloc_steal(), but you must supply the old
793 parent. This resolves the ambiguity in a talloc_steal() which is
794 called on a context that has more than one parent (via references)
796 The old parent can be either a reference or a parent
798 void *talloc_reparent(const void *old_parent, const void *new_parent, const void *ptr)
800 struct talloc_chunk *tc;
801 struct talloc_reference_handle *h;
803 if (unlikely(ptr == NULL)) {
804 return NULL;
807 if (old_parent == talloc_parent(ptr)) {
808 return _talloc_steal_internal(new_parent, ptr);
811 tc = talloc_chunk_from_ptr(ptr);
812 for (h=tc->refs;h;h=h->next) {
813 if (talloc_parent(h) == old_parent) {
814 if (_talloc_steal_internal(new_parent, h) != h) {
815 return NULL;
817 return discard_const_p(void, ptr);
821 /* it wasn't a parent */
822 return NULL;
826 remove a secondary reference to a pointer. This undo's what
827 talloc_reference() has done. The context and pointer arguments
828 must match those given to a talloc_reference()
830 static inline int talloc_unreference(const void *context, const void *ptr)
832 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
833 struct talloc_reference_handle *h;
835 if (unlikely(context == NULL)) {
836 context = null_context;
839 for (h=tc->refs;h;h=h->next) {
840 struct talloc_chunk *p = talloc_parent_chunk(h);
841 if (p == NULL) {
842 if (context == NULL) break;
843 } else if (TC_PTR_FROM_CHUNK(p) == context) {
844 break;
847 if (h == NULL) {
848 return -1;
851 return _talloc_free_internal(h, __location__);
855 remove a specific parent context from a pointer. This is a more
856 controlled varient of talloc_free()
858 int talloc_unlink(const void *context, void *ptr)
860 struct talloc_chunk *tc_p, *new_p;
861 void *new_parent;
863 if (ptr == NULL) {
864 return -1;
867 if (context == NULL) {
868 context = null_context;
871 if (talloc_unreference(context, ptr) == 0) {
872 return 0;
875 if (context == NULL) {
876 if (talloc_parent_chunk(ptr) != NULL) {
877 return -1;
879 } else {
880 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
881 return -1;
885 tc_p = talloc_chunk_from_ptr(ptr);
887 if (tc_p->refs == NULL) {
888 return _talloc_free_internal(ptr, __location__);
891 new_p = talloc_parent_chunk(tc_p->refs);
892 if (new_p) {
893 new_parent = TC_PTR_FROM_CHUNK(new_p);
894 } else {
895 new_parent = NULL;
898 if (talloc_unreference(new_parent, ptr) != 0) {
899 return -1;
902 _talloc_steal_internal(new_parent, ptr);
904 return 0;
908 add a name to an existing pointer - va_list version
910 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
912 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
914 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
915 tc->name = talloc_vasprintf(ptr, fmt, ap);
916 if (likely(tc->name)) {
917 _talloc_set_name_const(tc->name, ".name");
919 return tc->name;
923 add a name to an existing pointer
925 const char *talloc_set_name(const void *ptr, const char *fmt, ...)
927 const char *name;
928 va_list ap;
929 va_start(ap, fmt);
930 name = talloc_set_name_v(ptr, fmt, ap);
931 va_end(ap);
932 return name;
937 create a named talloc pointer. Any talloc pointer can be named, and
938 talloc_named() operates just like talloc() except that it allows you
939 to name the pointer.
941 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
943 va_list ap;
944 void *ptr;
945 const char *name;
947 ptr = __talloc(context, size);
948 if (unlikely(ptr == NULL)) return NULL;
950 va_start(ap, fmt);
951 name = talloc_set_name_v(ptr, fmt, ap);
952 va_end(ap);
954 if (unlikely(name == NULL)) {
955 _talloc_free_internal(ptr, __location__);
956 return NULL;
959 return ptr;
963 return the name of a talloc ptr, or "UNNAMED"
965 const char *talloc_get_name(const void *ptr)
967 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
968 if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
969 return ".reference";
971 if (likely(tc->name)) {
972 return tc->name;
974 return "UNNAMED";
979 check if a pointer has the given name. If it does, return the pointer,
980 otherwise return NULL
982 void *talloc_check_name(const void *ptr, const char *name)
984 const char *pname;
985 if (unlikely(ptr == NULL)) return NULL;
986 pname = talloc_get_name(ptr);
987 if (likely(pname == name || strcmp(pname, name) == 0)) {
988 return discard_const_p(void, ptr);
990 return NULL;
993 static void talloc_abort_type_missmatch(const char *location,
994 const char *name,
995 const char *expected)
997 const char *reason;
999 reason = talloc_asprintf(NULL,
1000 "%s: Type mismatch: name[%s] expected[%s]",
1001 location,
1002 name?name:"NULL",
1003 expected);
1004 if (!reason) {
1005 reason = "Type mismatch";
1008 talloc_abort(reason);
1011 void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location)
1013 const char *pname;
1015 if (unlikely(ptr == NULL)) {
1016 talloc_abort_type_missmatch(location, NULL, name);
1017 return NULL;
1020 pname = talloc_get_name(ptr);
1021 if (likely(pname == name || strcmp(pname, name) == 0)) {
1022 return discard_const_p(void, ptr);
1025 talloc_abort_type_missmatch(location, pname, name);
1026 return NULL;
1030 this is for compatibility with older versions of talloc
1032 void *talloc_init(const char *fmt, ...)
1034 va_list ap;
1035 void *ptr;
1036 const char *name;
1039 * samba3 expects talloc_report_depth_cb(NULL, ...)
1040 * reports all talloc'ed memory, so we need to enable
1041 * null_tracking
1043 talloc_enable_null_tracking();
1045 ptr = __talloc(NULL, 0);
1046 if (unlikely(ptr == NULL)) return NULL;
1048 va_start(ap, fmt);
1049 name = talloc_set_name_v(ptr, fmt, ap);
1050 va_end(ap);
1052 if (unlikely(name == NULL)) {
1053 _talloc_free_internal(ptr, __location__);
1054 return NULL;
1057 return ptr;
1061 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
1062 should probably not be used in new code. It's in here to keep the talloc
1063 code consistent across Samba 3 and 4.
1065 void talloc_free_children(void *ptr)
1067 struct talloc_chunk *tc;
1069 if (unlikely(ptr == NULL)) {
1070 return;
1073 tc = talloc_chunk_from_ptr(ptr);
1075 while (tc->child) {
1076 /* we need to work out who will own an abandoned child
1077 if it cannot be freed. In priority order, the first
1078 choice is owner of any remaining reference to this
1079 pointer, the second choice is our parent, and the
1080 final choice is the null context. */
1081 void *child = TC_PTR_FROM_CHUNK(tc->child);
1082 const void *new_parent = null_context;
1083 if (unlikely(tc->child->refs)) {
1084 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
1085 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
1087 if (unlikely(talloc_free(child) == -1)) {
1088 if (new_parent == null_context) {
1089 struct talloc_chunk *p = talloc_parent_chunk(ptr);
1090 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
1092 _talloc_steal_internal(new_parent, child);
1096 if ((tc->flags & TALLOC_FLAG_POOL)
1097 && (*talloc_pool_objectcount(tc) == 1)) {
1098 tc->pool = ((char *)tc + TC_HDR_SIZE + TALLOC_POOL_HDR_SIZE);
1099 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
1100 VALGRIND_MAKE_MEM_NOACCESS(
1101 tc->pool, tc->size - TALLOC_POOL_HDR_SIZE);
1102 #endif
1107 Allocate a bit of memory as a child of an existing pointer
1109 void *_talloc(const void *context, size_t size)
1111 return __talloc(context, size);
1115 externally callable talloc_set_name_const()
1117 void talloc_set_name_const(const void *ptr, const char *name)
1119 _talloc_set_name_const(ptr, name);
1123 create a named talloc pointer. Any talloc pointer can be named, and
1124 talloc_named() operates just like talloc() except that it allows you
1125 to name the pointer.
1127 void *talloc_named_const(const void *context, size_t size, const char *name)
1129 return _talloc_named_const(context, size, name);
1133 free a talloc pointer. This also frees all child pointers of this
1134 pointer recursively
1136 return 0 if the memory is actually freed, otherwise -1. The memory
1137 will not be freed if the ref_count is > 1 or the destructor (if
1138 any) returns non-zero
1140 int _talloc_free(void *ptr, const char *location)
1142 struct talloc_chunk *tc;
1144 if (unlikely(ptr == NULL)) {
1145 return -1;
1148 tc = talloc_chunk_from_ptr(ptr);
1150 if (unlikely(tc->refs != NULL)) {
1151 struct talloc_reference_handle *h;
1153 talloc_log("ERROR: talloc_free with references at %s\n",
1154 location);
1156 for (h=tc->refs; h; h=h->next) {
1157 talloc_log("\treference at %s\n",
1158 h->location);
1160 return -1;
1163 return _talloc_free_internal(ptr, location);
1169 A talloc version of realloc. The context argument is only used if
1170 ptr is NULL
1172 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
1174 struct talloc_chunk *tc;
1175 void *new_ptr;
1176 bool malloced = false;
1178 /* size zero is equivalent to free() */
1179 if (unlikely(size == 0)) {
1180 talloc_unlink(context, ptr);
1181 return NULL;
1184 if (unlikely(size >= MAX_TALLOC_SIZE)) {
1185 return NULL;
1188 /* realloc(NULL) is equivalent to malloc() */
1189 if (ptr == NULL) {
1190 return _talloc_named_const(context, size, name);
1193 tc = talloc_chunk_from_ptr(ptr);
1195 /* don't allow realloc on referenced pointers */
1196 if (unlikely(tc->refs)) {
1197 return NULL;
1200 /* don't let anybody try to realloc a talloc_pool */
1201 if (unlikely(tc->flags & TALLOC_FLAG_POOL)) {
1202 return NULL;
1205 /* don't shrink if we have less than 1k to gain */
1206 if ((size < tc->size) && ((tc->size - size) < 1024)) {
1207 tc->size = size;
1208 return ptr;
1211 /* by resetting magic we catch users of the old memory */
1212 tc->flags |= TALLOC_FLAG_FREE;
1214 #if ALWAYS_REALLOC
1215 new_ptr = malloc(size + TC_HDR_SIZE);
1216 if (new_ptr) {
1217 memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
1218 free(tc);
1220 #else
1221 if (tc->flags & TALLOC_FLAG_POOLMEM) {
1223 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE);
1224 *talloc_pool_objectcount((struct talloc_chunk *)
1225 (tc->pool)) -= 1;
1227 if (new_ptr == NULL) {
1228 new_ptr = malloc(TC_HDR_SIZE+size);
1229 malloced = true;
1232 if (new_ptr) {
1233 memcpy(new_ptr, tc, TALLOC_MIN(tc->size,size) + TC_HDR_SIZE);
1236 else {
1237 new_ptr = realloc(tc, size + TC_HDR_SIZE);
1239 #endif
1240 if (unlikely(!new_ptr)) {
1241 tc->flags &= ~TALLOC_FLAG_FREE;
1242 return NULL;
1245 tc = (struct talloc_chunk *)new_ptr;
1246 tc->flags &= ~TALLOC_FLAG_FREE;
1247 if (malloced) {
1248 tc->flags &= ~TALLOC_FLAG_POOLMEM;
1250 if (tc->parent) {
1251 tc->parent->child = tc;
1253 if (tc->child) {
1254 tc->child->parent = tc;
1257 if (tc->prev) {
1258 tc->prev->next = tc;
1260 if (tc->next) {
1261 tc->next->prev = tc;
1264 tc->size = size;
1265 _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
1267 return TC_PTR_FROM_CHUNK(tc);
1271 a wrapper around talloc_steal() for situations where you are moving a pointer
1272 between two structures, and want the old pointer to be set to NULL
1274 void *_talloc_move(const void *new_ctx, const void *_pptr)
1276 const void **pptr = discard_const_p(const void *,_pptr);
1277 void *ret = talloc_steal(new_ctx, discard_const_p(void, *pptr));
1278 (*pptr) = NULL;
1279 return ret;
1283 return the total size of a talloc pool (subtree)
1285 size_t talloc_total_size(const void *ptr)
1287 size_t total = 0;
1288 struct talloc_chunk *c, *tc;
1290 if (ptr == NULL) {
1291 ptr = null_context;
1293 if (ptr == NULL) {
1294 return 0;
1297 tc = talloc_chunk_from_ptr(ptr);
1299 if (tc->flags & TALLOC_FLAG_LOOP) {
1300 return 0;
1303 tc->flags |= TALLOC_FLAG_LOOP;
1305 if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) {
1306 total = tc->size;
1308 for (c=tc->child;c;c=c->next) {
1309 total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
1312 tc->flags &= ~TALLOC_FLAG_LOOP;
1314 return total;
1318 return the total number of blocks in a talloc pool (subtree)
1320 size_t talloc_total_blocks(const void *ptr)
1322 size_t total = 0;
1323 struct talloc_chunk *c, *tc;
1325 if (ptr == NULL) {
1326 ptr = null_context;
1328 if (ptr == NULL) {
1329 return 0;
1332 tc = talloc_chunk_from_ptr(ptr);
1334 if (tc->flags & TALLOC_FLAG_LOOP) {
1335 return 0;
1338 tc->flags |= TALLOC_FLAG_LOOP;
1340 total++;
1341 for (c=tc->child;c;c=c->next) {
1342 total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
1345 tc->flags &= ~TALLOC_FLAG_LOOP;
1347 return total;
1351 return the number of external references to a pointer
1353 size_t talloc_reference_count(const void *ptr)
1355 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1356 struct talloc_reference_handle *h;
1357 size_t ret = 0;
1359 for (h=tc->refs;h;h=h->next) {
1360 ret++;
1362 return ret;
1366 report on memory usage by all children of a pointer, giving a full tree view
1368 void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
1369 void (*callback)(const void *ptr,
1370 int depth, int max_depth,
1371 int is_ref,
1372 void *private_data),
1373 void *private_data)
1375 struct talloc_chunk *c, *tc;
1377 if (ptr == NULL) {
1378 ptr = null_context;
1380 if (ptr == NULL) return;
1382 tc = talloc_chunk_from_ptr(ptr);
1384 if (tc->flags & TALLOC_FLAG_LOOP) {
1385 return;
1388 callback(ptr, depth, max_depth, 0, private_data);
1390 if (max_depth >= 0 && depth >= max_depth) {
1391 return;
1394 tc->flags |= TALLOC_FLAG_LOOP;
1395 for (c=tc->child;c;c=c->next) {
1396 if (c->name == TALLOC_MAGIC_REFERENCE) {
1397 struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
1398 callback(h->ptr, depth + 1, max_depth, 1, private_data);
1399 } else {
1400 talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
1403 tc->flags &= ~TALLOC_FLAG_LOOP;
1406 static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
1408 const char *name = talloc_get_name(ptr);
1409 FILE *f = (FILE *)_f;
1411 if (is_ref) {
1412 fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
1413 return;
1416 if (depth == 0) {
1417 fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n",
1418 (max_depth < 0 ? "full " :""), name,
1419 (unsigned long)talloc_total_size(ptr),
1420 (unsigned long)talloc_total_blocks(ptr));
1421 return;
1424 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
1425 depth*4, "",
1426 name,
1427 (unsigned long)talloc_total_size(ptr),
1428 (unsigned long)talloc_total_blocks(ptr),
1429 (int)talloc_reference_count(ptr), ptr);
1431 #if 0
1432 fprintf(f, "content: ");
1433 if (talloc_total_size(ptr)) {
1434 int tot = talloc_total_size(ptr);
1435 int i;
1437 for (i = 0; i < tot; i++) {
1438 if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
1439 fprintf(f, "%c", ((char *)ptr)[i]);
1440 } else {
1441 fprintf(f, "~%02x", ((char *)ptr)[i]);
1445 fprintf(f, "\n");
1446 #endif
1450 report on memory usage by all children of a pointer, giving a full tree view
1452 void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
1454 if (f) {
1455 talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
1456 fflush(f);
1461 report on memory usage by all children of a pointer, giving a full tree view
1463 void talloc_report_full(const void *ptr, FILE *f)
1465 talloc_report_depth_file(ptr, 0, -1, f);
1469 report on memory usage by all children of a pointer
1471 void talloc_report(const void *ptr, FILE *f)
1473 talloc_report_depth_file(ptr, 0, 1, f);
1477 report on any memory hanging off the null context
1479 static void talloc_report_null(void)
1481 if (talloc_total_size(null_context) != 0) {
1482 talloc_report(null_context, stderr);
1487 report on any memory hanging off the null context
1489 static void talloc_report_null_full(void)
1491 if (talloc_total_size(null_context) != 0) {
1492 talloc_report_full(null_context, stderr);
1497 enable tracking of the NULL context
1499 void talloc_enable_null_tracking(void)
1501 if (null_context == NULL) {
1502 null_context = _talloc_named_const(NULL, 0, "null_context");
1503 if (autofree_context != NULL) {
1504 talloc_reparent(NULL, null_context, autofree_context);
1510 enable tracking of the NULL context, not moving the autofree context
1511 into the NULL context. This is needed for the talloc testsuite
1513 void talloc_enable_null_tracking_no_autofree(void)
1515 if (null_context == NULL) {
1516 null_context = _talloc_named_const(NULL, 0, "null_context");
1521 disable tracking of the NULL context
1523 void talloc_disable_null_tracking(void)
1525 if (null_context != NULL) {
1526 /* we have to move any children onto the real NULL
1527 context */
1528 struct talloc_chunk *tc, *tc2;
1529 tc = talloc_chunk_from_ptr(null_context);
1530 for (tc2 = tc->child; tc2; tc2=tc2->next) {
1531 if (tc2->parent == tc) tc2->parent = NULL;
1532 if (tc2->prev == tc) tc2->prev = NULL;
1534 for (tc2 = tc->next; tc2; tc2=tc2->next) {
1535 if (tc2->parent == tc) tc2->parent = NULL;
1536 if (tc2->prev == tc) tc2->prev = NULL;
1538 tc->child = NULL;
1539 tc->next = NULL;
1541 talloc_free(null_context);
1542 null_context = NULL;
1546 enable leak reporting on exit
1548 void talloc_enable_leak_report(void)
1550 talloc_enable_null_tracking();
1551 atexit(talloc_report_null);
1555 enable full leak reporting on exit
1557 void talloc_enable_leak_report_full(void)
1559 talloc_enable_null_tracking();
1560 atexit(talloc_report_null_full);
1564 talloc and zero memory.
1566 void *_talloc_zero(const void *ctx, size_t size, const char *name)
1568 void *p = _talloc_named_const(ctx, size, name);
1570 if (p) {
1571 memset(p, '\0', size);
1574 return p;
1578 memdup with a talloc.
1580 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
1582 void *newp = _talloc_named_const(t, size, name);
1584 if (likely(newp)) {
1585 memcpy(newp, p, size);
1588 return newp;
1591 static inline char *__talloc_strlendup(const void *t, const char *p, size_t len)
1593 char *ret;
1595 ret = (char *)__talloc(t, len + 1);
1596 if (unlikely(!ret)) return NULL;
1598 memcpy(ret, p, len);
1599 ret[len] = 0;
1601 _talloc_set_name_const(ret, ret);
1602 return ret;
1606 strdup with a talloc
1608 char *talloc_strdup(const void *t, const char *p)
1610 if (unlikely(!p)) return NULL;
1611 return __talloc_strlendup(t, p, strlen(p));
1615 strndup with a talloc
1617 char *talloc_strndup(const void *t, const char *p, size_t n)
1619 if (unlikely(!p)) return NULL;
1620 return __talloc_strlendup(t, p, strnlen(p, n));
1623 static inline char *__talloc_strlendup_append(char *s, size_t slen,
1624 const char *a, size_t alen)
1626 char *ret;
1628 ret = talloc_realloc(NULL, s, char, slen + alen + 1);
1629 if (unlikely(!ret)) return NULL;
1631 /* append the string and the trailing \0 */
1632 memcpy(&ret[slen], a, alen);
1633 ret[slen+alen] = 0;
1635 _talloc_set_name_const(ret, ret);
1636 return ret;
1640 * Appends at the end of the string.
1642 char *talloc_strdup_append(char *s, const char *a)
1644 if (unlikely(!s)) {
1645 return talloc_strdup(NULL, a);
1648 if (unlikely(!a)) {
1649 return s;
1652 return __talloc_strlendup_append(s, strlen(s), a, strlen(a));
1656 * Appends at the end of the talloc'ed buffer,
1657 * not the end of the string.
1659 char *talloc_strdup_append_buffer(char *s, const char *a)
1661 size_t slen;
1663 if (unlikely(!s)) {
1664 return talloc_strdup(NULL, a);
1667 if (unlikely(!a)) {
1668 return s;
1671 slen = talloc_get_size(s);
1672 if (likely(slen > 0)) {
1673 slen--;
1676 return __talloc_strlendup_append(s, slen, a, strlen(a));
1680 * Appends at the end of the string.
1682 char *talloc_strndup_append(char *s, const char *a, size_t n)
1684 if (unlikely(!s)) {
1685 return talloc_strdup(NULL, a);
1688 if (unlikely(!a)) {
1689 return s;
1692 return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n));
1696 * Appends at the end of the talloc'ed buffer,
1697 * not the end of the string.
1699 char *talloc_strndup_append_buffer(char *s, const char *a, size_t n)
1701 size_t slen;
1703 if (unlikely(!s)) {
1704 return talloc_strdup(NULL, a);
1707 if (unlikely(!a)) {
1708 return s;
1711 slen = talloc_get_size(s);
1712 if (likely(slen > 0)) {
1713 slen--;
1716 return __talloc_strlendup_append(s, slen, a, strnlen(a, n));
1719 #ifndef va_copy
1720 #ifdef HAVE___VA_COPY
1721 #define va_copy(dest, src) __va_copy(dest, src)
1722 #else
1723 #define va_copy(dest, src) (dest) = (src)
1724 #endif
1725 #endif
1727 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1729 int len;
1730 char *ret;
1731 va_list ap2;
1732 char c;
1734 /* this call looks strange, but it makes it work on older solaris boxes */
1735 va_copy(ap2, ap);
1736 #ifdef _MSC_VER
1737 /* MSVC runtime needs to use _vcsprintf to return buffer size; vsnprintf would return -1 */
1738 len = _vscprintf(fmt, ap2);
1739 #else
1740 len = vsnprintf(&c, 1, fmt, ap2);
1741 #endif
1742 va_end(ap2);
1743 if (unlikely(len < 0)) {
1744 return NULL;
1747 ret = (char *)__talloc(t, len+1);
1748 if (unlikely(!ret)) return NULL;
1750 va_copy(ap2, ap);
1751 vsnprintf(ret, len+1, fmt, ap2);
1752 va_end(ap2);
1754 _talloc_set_name_const(ret, ret);
1755 return ret;
1760 Perform string formatting, and return a pointer to newly allocated
1761 memory holding the result, inside a memory pool.
1763 char *talloc_asprintf(const void *t, const char *fmt, ...)
1765 va_list ap;
1766 char *ret;
1768 va_start(ap, fmt);
1769 ret = talloc_vasprintf(t, fmt, ap);
1770 va_end(ap);
1771 return ret;
1774 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
1775 const char *fmt, va_list ap)
1776 PRINTF_ATTRIBUTE(3,0);
1778 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
1779 const char *fmt, va_list ap)
1781 ssize_t alen;
1782 va_list ap2;
1783 char c;
1785 va_copy(ap2, ap);
1786 #ifdef _MSC_VER
1787 /* MSVC runtime needs to use _vcsprintf to return buffer size; vsnprintf would return -1 */
1788 alen = _vscprintf(fmt, ap2);
1789 #else
1790 alen = vsnprintf(&c, 1, fmt, ap2);
1791 #endif
1792 va_end(ap2);
1794 if (alen <= 0) {
1795 /* Either the vsnprintf failed or the format resulted in
1796 * no characters being formatted. In the former case, we
1797 * ought to return NULL, in the latter we ought to return
1798 * the original string. Most current callers of this
1799 * function expect it to never return NULL.
1801 return s;
1804 s = talloc_realloc(NULL, s, char, slen + alen + 1);
1805 if (!s) return NULL;
1807 va_copy(ap2, ap);
1808 vsnprintf(s + slen, alen + 1, fmt, ap2);
1809 va_end(ap2);
1811 _talloc_set_name_const(s, s);
1812 return s;
1816 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1817 * and return @p s, which may have moved. Good for gradually
1818 * accumulating output into a string buffer. Appends at the end
1819 * of the string.
1821 char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1823 if (unlikely(!s)) {
1824 return talloc_vasprintf(NULL, fmt, ap);
1827 return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap);
1831 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1832 * and return @p s, which may have moved. Always appends at the
1833 * end of the talloc'ed buffer, not the end of the string.
1835 char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap)
1837 size_t slen;
1839 if (unlikely(!s)) {
1840 return talloc_vasprintf(NULL, fmt, ap);
1843 slen = talloc_get_size(s);
1844 if (likely(slen > 0)) {
1845 slen--;
1848 return __talloc_vaslenprintf_append(s, slen, fmt, ap);
1852 Realloc @p s to append the formatted result of @p fmt and return @p
1853 s, which may have moved. Good for gradually accumulating output
1854 into a string buffer.
1856 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1858 va_list ap;
1860 va_start(ap, fmt);
1861 s = talloc_vasprintf_append(s, fmt, ap);
1862 va_end(ap);
1863 return s;
1867 Realloc @p s to append the formatted result of @p fmt and return @p
1868 s, which may have moved. Good for gradually accumulating output
1869 into a buffer.
1871 char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...)
1873 va_list ap;
1875 va_start(ap, fmt);
1876 s = talloc_vasprintf_append_buffer(s, fmt, ap);
1877 va_end(ap);
1878 return s;
1882 alloc an array, checking for integer overflow in the array size
1884 void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1886 if (count >= MAX_TALLOC_SIZE/el_size) {
1887 return NULL;
1889 return _talloc_named_const(ctx, el_size * count, name);
1893 alloc an zero array, checking for integer overflow in the array size
1895 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1897 if (count >= MAX_TALLOC_SIZE/el_size) {
1898 return NULL;
1900 return _talloc_zero(ctx, el_size * count, name);
1904 realloc an array, checking for integer overflow in the array size
1906 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1908 if (count >= MAX_TALLOC_SIZE/el_size) {
1909 return NULL;
1911 return _talloc_realloc(ctx, ptr, el_size * count, name);
1915 a function version of talloc_realloc(), so it can be passed as a function pointer
1916 to libraries that want a realloc function (a realloc function encapsulates
1917 all the basic capabilities of an allocation library, which is why this is useful)
1919 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1921 return _talloc_realloc(context, ptr, size, NULL);
1925 static int talloc_autofree_destructor(void *ptr)
1927 autofree_context = NULL;
1928 return 0;
1931 static void talloc_autofree(void)
1933 talloc_free(autofree_context);
1937 return a context which will be auto-freed on exit
1938 this is useful for reducing the noise in leak reports
1940 void *talloc_autofree_context(void)
1942 if (autofree_context == NULL) {
1943 autofree_context = _talloc_named_const(NULL, 0, "autofree_context");
1944 talloc_set_destructor(autofree_context, talloc_autofree_destructor);
1945 atexit(talloc_autofree);
1947 return autofree_context;
1950 size_t talloc_get_size(const void *context)
1952 struct talloc_chunk *tc;
1954 if (context == NULL) {
1955 context = null_context;
1957 if (context == NULL) {
1958 return 0;
1961 tc = talloc_chunk_from_ptr(context);
1963 return tc->size;
1967 find a parent of this context that has the given name, if any
1969 void *talloc_find_parent_byname(const void *context, const char *name)
1971 struct talloc_chunk *tc;
1973 if (context == NULL) {
1974 return NULL;
1977 tc = talloc_chunk_from_ptr(context);
1978 while (tc) {
1979 if (tc->name && strcmp(tc->name, name) == 0) {
1980 return TC_PTR_FROM_CHUNK(tc);
1982 while (tc && tc->prev) tc = tc->prev;
1983 if (tc) {
1984 tc = tc->parent;
1987 return NULL;
1991 show the parentage of a context
1993 void talloc_show_parents(const void *context, FILE *file)
1995 struct talloc_chunk *tc;
1997 if (context == NULL) {
1998 fprintf(file, "talloc no parents for NULL\n");
1999 return;
2002 tc = talloc_chunk_from_ptr(context);
2003 fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
2004 while (tc) {
2005 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
2006 while (tc && tc->prev) tc = tc->prev;
2007 if (tc) {
2008 tc = tc->parent;
2011 fflush(file);
2015 return 1 if ptr is a parent of context
2017 int talloc_is_parent(const void *context, const void *ptr)
2019 struct talloc_chunk *tc;
2021 if (context == NULL) {
2022 return 0;
2025 tc = talloc_chunk_from_ptr(context);
2026 while (tc) {
2027 if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
2028 while (tc && tc->prev) tc = tc->prev;
2029 if (tc) {
2030 tc = tc->parent;
2033 return 0;