2 Samba Unix SMB/CIFS implementation.
4 Samba trivial allocation library - new interface
6 NOTE: Please read talloc_guide.txt for full documentation
8 Copyright (C) Andrew Tridgell 2004
9 Copyright (C) Stefan Metzmacher 2006
11 ** NOTE! The following LGPL license applies to the talloc
12 ** library. This does NOT imply that all of Samba is released
15 This library is free software; you can redistribute it and/or
16 modify it under the terms of the GNU Lesser General Public
17 License as published by the Free Software Foundation; either
18 version 3 of the License, or (at your option) any later version.
20 This library is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 Lesser General Public License for more details.
25 You should have received a copy of the GNU Lesser General Public
26 License along with this library; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 inspired by http://swapped.cc/halloc/
36 #if (SAMBA_VERSION_MAJOR<4)
38 /* This is to circumvent SAMBA3's paranoid malloc checker. Here in this file
39 * we trust ourselves... */
46 #define _TALLOC_SAMBA3
47 #endif /* (SAMBA_VERSION_MAJOR<4) */
48 #endif /* _SAMBA_BUILD_ */
50 #ifndef _TALLOC_SAMBA3
53 #endif /* not _TALLOC_SAMBA3 */
55 /* use this to force every realloc to change the pointer, to stress test
56 code that might not cope */
57 #define ALWAYS_REALLOC 0
60 #define MAX_TALLOC_SIZE 0x10000000
61 #define TALLOC_MAGIC 0xe814ec70
62 #define TALLOC_FLAG_FREE 0x01
63 #define TALLOC_FLAG_LOOP 0x02
64 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
66 /* by default we abort when given a bad pointer (such as when talloc_free() is called
67 on a pointer that came from malloc() */
69 #define TALLOC_ABORT(reason) abort()
72 #ifndef discard_const_p
73 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
74 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
76 # define discard_const_p(type, ptr) ((type *)(ptr))
80 /* these macros gain us a few percent of speed on gcc */
82 /* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
83 as its first argument */
84 #define likely(x) __builtin_expect(!!(x), 1)
85 #define unlikely(x) __builtin_expect(!!(x), 0)
91 /* this null_context is only used if talloc_enable_leak_report() or
92 talloc_enable_leak_report_full() is called, otherwise it remains
95 static void *null_context;
96 static void *autofree_context;
98 struct talloc_reference_handle {
99 struct talloc_reference_handle *next, *prev;
103 typedef int (*talloc_destructor_t)(void *);
105 struct talloc_chunk {
106 struct talloc_chunk *next, *prev;
107 struct talloc_chunk *parent, *child;
108 struct talloc_reference_handle *refs;
109 talloc_destructor_t destructor;
115 /* 16 byte alignment seems to keep everyone happy */
116 #define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
117 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
119 /* panic if we get a bad magic value */
120 static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
122 const char *pp = (const char *)ptr;
123 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
124 if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) {
125 if (tc->flags & TALLOC_FLAG_FREE) {
126 TALLOC_ABORT("Bad talloc magic value - double free");
128 TALLOC_ABORT("Bad talloc magic value - unknown value");
134 /* hook into the front of the list */
135 #define _TLIST_ADD(list, p) \
139 (p)->next = (p)->prev = NULL; \
141 (list)->prev = (p); \
142 (p)->next = (list); \
148 /* remove an element from a list - element doesn't have to be in list. */
149 #define _TLIST_REMOVE(list, p) \
151 if ((p) == (list)) { \
152 (list) = (p)->next; \
153 if (list) (list)->prev = NULL; \
155 if ((p)->prev) (p)->prev->next = (p)->next; \
156 if ((p)->next) (p)->next->prev = (p)->prev; \
158 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
163 return the parent chunk of a pointer
165 static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr)
167 struct talloc_chunk *tc;
169 if (unlikely(ptr == NULL)) {
173 tc = talloc_chunk_from_ptr(ptr);
174 while (tc->prev) tc=tc->prev;
179 void *talloc_parent(const void *ptr)
181 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
182 return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
188 const char *talloc_parent_name(const void *ptr)
190 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
191 return tc? tc->name : NULL;
195 Allocate a bit of memory as a child of an existing pointer
197 static inline void *__talloc(const void *context, size_t size)
199 struct talloc_chunk *tc;
201 if (unlikely(context == NULL)) {
202 context = null_context;
205 if (unlikely(size >= MAX_TALLOC_SIZE)) {
209 tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size);
210 if (unlikely(tc == NULL)) return NULL;
213 tc->flags = TALLOC_MAGIC;
214 tc->destructor = NULL;
219 if (likely(context)) {
220 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
223 parent->child->parent = NULL;
224 tc->next = parent->child;
233 tc->next = tc->prev = tc->parent = NULL;
236 return TC_PTR_FROM_CHUNK(tc);
240 setup a destructor to be called on free of a pointer
241 the destructor should return 0 on success, or -1 on failure.
242 if the destructor fails then the free is failed, and the memory can
243 be continued to be used
245 void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
247 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
248 tc->destructor = destructor;
252 increase the reference count on a piece of memory.
254 int talloc_increase_ref_count(const void *ptr)
256 if (unlikely(!talloc_reference(null_context, ptr))) {
263 helper for talloc_reference()
265 this is referenced by a function pointer and should not be inline
267 static int talloc_reference_destructor(struct talloc_reference_handle *handle)
269 struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
270 _TLIST_REMOVE(ptr_tc->refs, handle);
275 more efficient way to add a name to a pointer - the name must point to a
278 static inline void _talloc_set_name_const(const void *ptr, const char *name)
280 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
285 internal talloc_named_const()
287 static inline void *_talloc_named_const(const void *context, size_t size, const char *name)
291 ptr = __talloc(context, size);
292 if (unlikely(ptr == NULL)) {
296 _talloc_set_name_const(ptr, name);
302 make a secondary reference to a pointer, hanging off the given context.
303 the pointer remains valid until both the original caller and this given
306 the major use for this is when two different structures need to reference the
307 same underlying data, and you want to be able to free the two instances separately,
310 void *_talloc_reference(const void *context, const void *ptr)
312 struct talloc_chunk *tc;
313 struct talloc_reference_handle *handle;
314 if (unlikely(ptr == NULL)) return NULL;
316 tc = talloc_chunk_from_ptr(ptr);
317 handle = (struct talloc_reference_handle *)_talloc_named_const(context,
318 sizeof(struct talloc_reference_handle),
319 TALLOC_MAGIC_REFERENCE);
320 if (unlikely(handle == NULL)) return NULL;
322 /* note that we hang the destructor off the handle, not the
323 main context as that allows the caller to still setup their
324 own destructor on the context if they want to */
325 talloc_set_destructor(handle, talloc_reference_destructor);
326 handle->ptr = discard_const_p(void, ptr);
327 _TLIST_ADD(tc->refs, handle);
333 internal talloc_free call
335 static inline int _talloc_free(void *ptr)
337 struct talloc_chunk *tc;
339 if (unlikely(ptr == NULL)) {
343 tc = talloc_chunk_from_ptr(ptr);
345 if (unlikely(tc->refs)) {
347 /* check this is a reference from a child or grantchild
348 * back to it's parent or grantparent
350 * in that case we need to remove the reference and
351 * call another instance of talloc_free() on the current
354 is_child = talloc_is_parent(tc->refs, ptr);
355 _talloc_free(tc->refs);
357 return _talloc_free(ptr);
362 if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) {
363 /* we have a free loop - stop looping */
367 if (unlikely(tc->destructor)) {
368 talloc_destructor_t d = tc->destructor;
369 if (d == (talloc_destructor_t)-1) {
372 tc->destructor = (talloc_destructor_t)-1;
377 tc->destructor = NULL;
381 _TLIST_REMOVE(tc->parent->child, tc);
382 if (tc->parent->child) {
383 tc->parent->child->parent = tc->parent;
386 if (tc->prev) tc->prev->next = tc->next;
387 if (tc->next) tc->next->prev = tc->prev;
390 tc->flags |= TALLOC_FLAG_LOOP;
393 /* we need to work out who will own an abandoned child
394 if it cannot be freed. In priority order, the first
395 choice is owner of any remaining reference to this
396 pointer, the second choice is our parent, and the
397 final choice is the null context. */
398 void *child = TC_PTR_FROM_CHUNK(tc->child);
399 const void *new_parent = null_context;
400 if (unlikely(tc->child->refs)) {
401 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
402 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
404 if (unlikely(_talloc_free(child) == -1)) {
405 if (new_parent == null_context) {
406 struct talloc_chunk *p = talloc_parent_chunk(ptr);
407 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
409 talloc_steal(new_parent, child);
413 tc->flags |= TALLOC_FLAG_FREE;
419 move a lump of memory from one talloc context to another return the
420 ptr on success, or NULL if it could not be transferred.
421 passing NULL as ptr will always return NULL with no side effects.
423 void *_talloc_steal(const void *new_ctx, const void *ptr)
425 struct talloc_chunk *tc, *new_tc;
427 if (unlikely(!ptr)) {
431 if (unlikely(new_ctx == NULL)) {
432 new_ctx = null_context;
435 tc = talloc_chunk_from_ptr(ptr);
437 if (unlikely(new_ctx == NULL)) {
439 _TLIST_REMOVE(tc->parent->child, tc);
440 if (tc->parent->child) {
441 tc->parent->child->parent = tc->parent;
444 if (tc->prev) tc->prev->next = tc->next;
445 if (tc->next) tc->next->prev = tc->prev;
448 tc->parent = tc->next = tc->prev = NULL;
449 return discard_const_p(void, ptr);
452 new_tc = talloc_chunk_from_ptr(new_ctx);
454 if (unlikely(tc == new_tc || tc->parent == new_tc)) {
455 return discard_const_p(void, ptr);
459 _TLIST_REMOVE(tc->parent->child, tc);
460 if (tc->parent->child) {
461 tc->parent->child->parent = tc->parent;
464 if (tc->prev) tc->prev->next = tc->next;
465 if (tc->next) tc->next->prev = tc->prev;
469 if (new_tc->child) new_tc->child->parent = NULL;
470 _TLIST_ADD(new_tc->child, tc);
472 return discard_const_p(void, ptr);
478 remove a secondary reference to a pointer. This undo's what
479 talloc_reference() has done. The context and pointer arguments
480 must match those given to a talloc_reference()
482 static inline int talloc_unreference(const void *context, const void *ptr)
484 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
485 struct talloc_reference_handle *h;
487 if (unlikely(context == NULL)) {
488 context = null_context;
491 for (h=tc->refs;h;h=h->next) {
492 struct talloc_chunk *p = talloc_parent_chunk(h);
494 if (context == NULL) break;
495 } else if (TC_PTR_FROM_CHUNK(p) == context) {
503 return _talloc_free(h);
507 remove a specific parent context from a pointer. This is a more
508 controlled varient of talloc_free()
510 int talloc_unlink(const void *context, void *ptr)
512 struct talloc_chunk *tc_p, *new_p;
519 if (context == NULL) {
520 context = null_context;
523 if (talloc_unreference(context, ptr) == 0) {
527 if (context == NULL) {
528 if (talloc_parent_chunk(ptr) != NULL) {
532 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
537 tc_p = talloc_chunk_from_ptr(ptr);
539 if (tc_p->refs == NULL) {
540 return _talloc_free(ptr);
543 new_p = talloc_parent_chunk(tc_p->refs);
545 new_parent = TC_PTR_FROM_CHUNK(new_p);
550 if (talloc_unreference(new_parent, ptr) != 0) {
554 talloc_steal(new_parent, ptr);
560 add a name to an existing pointer - va_list version
562 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
564 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
566 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
567 tc->name = talloc_vasprintf(ptr, fmt, ap);
568 if (likely(tc->name)) {
569 _talloc_set_name_const(tc->name, ".name");
575 add a name to an existing pointer
577 const char *talloc_set_name(const void *ptr, const char *fmt, ...)
582 name = talloc_set_name_v(ptr, fmt, ap);
589 create a named talloc pointer. Any talloc pointer can be named, and
590 talloc_named() operates just like talloc() except that it allows you
593 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
599 ptr = __talloc(context, size);
600 if (unlikely(ptr == NULL)) return NULL;
603 name = talloc_set_name_v(ptr, fmt, ap);
606 if (unlikely(name == NULL)) {
615 return the name of a talloc ptr, or "UNNAMED"
617 const char *talloc_get_name(const void *ptr)
619 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
620 if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
623 if (likely(tc->name)) {
631 check if a pointer has the given name. If it does, return the pointer,
632 otherwise return NULL
634 void *talloc_check_name(const void *ptr, const char *name)
637 if (unlikely(ptr == NULL)) return NULL;
638 pname = talloc_get_name(ptr);
639 if (likely(pname == name || strcmp(pname, name) == 0)) {
640 return discard_const_p(void, ptr);
647 this is for compatibility with older versions of talloc
649 void *talloc_init(const char *fmt, ...)
656 * samba3 expects talloc_report_depth_cb(NULL, ...)
657 * reports all talloc'ed memory, so we need to enable
660 talloc_enable_null_tracking();
662 ptr = __talloc(NULL, 0);
663 if (unlikely(ptr == NULL)) return NULL;
666 name = talloc_set_name_v(ptr, fmt, ap);
669 if (unlikely(name == NULL)) {
678 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
679 should probably not be used in new code. It's in here to keep the talloc
680 code consistent across Samba 3 and 4.
682 void talloc_free_children(void *ptr)
684 struct talloc_chunk *tc;
686 if (unlikely(ptr == NULL)) {
690 tc = talloc_chunk_from_ptr(ptr);
693 /* we need to work out who will own an abandoned child
694 if it cannot be freed. In priority order, the first
695 choice is owner of any remaining reference to this
696 pointer, the second choice is our parent, and the
697 final choice is the null context. */
698 void *child = TC_PTR_FROM_CHUNK(tc->child);
699 const void *new_parent = null_context;
700 if (unlikely(tc->child->refs)) {
701 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
702 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
704 if (unlikely(_talloc_free(child) == -1)) {
705 if (new_parent == null_context) {
706 struct talloc_chunk *p = talloc_parent_chunk(ptr);
707 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
709 talloc_steal(new_parent, child);
715 Allocate a bit of memory as a child of an existing pointer
717 void *_talloc(const void *context, size_t size)
719 return __talloc(context, size);
723 externally callable talloc_set_name_const()
725 void talloc_set_name_const(const void *ptr, const char *name)
727 _talloc_set_name_const(ptr, name);
731 create a named talloc pointer. Any talloc pointer can be named, and
732 talloc_named() operates just like talloc() except that it allows you
735 void *talloc_named_const(const void *context, size_t size, const char *name)
737 return _talloc_named_const(context, size, name);
741 free a talloc pointer. This also frees all child pointers of this
744 return 0 if the memory is actually freed, otherwise -1. The memory
745 will not be freed if the ref_count is > 1 or the destructor (if
746 any) returns non-zero
748 int talloc_free(void *ptr)
750 return _talloc_free(ptr);
756 A talloc version of realloc. The context argument is only used if
759 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
761 struct talloc_chunk *tc;
764 /* size zero is equivalent to free() */
765 if (unlikely(size == 0)) {
770 if (unlikely(size >= MAX_TALLOC_SIZE)) {
774 /* realloc(NULL) is equivalent to malloc() */
776 return _talloc_named_const(context, size, name);
779 tc = talloc_chunk_from_ptr(ptr);
781 /* don't allow realloc on referenced pointers */
782 if (unlikely(tc->refs)) {
786 /* by resetting magic we catch users of the old memory */
787 tc->flags |= TALLOC_FLAG_FREE;
790 new_ptr = malloc(size + TC_HDR_SIZE);
792 memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
796 new_ptr = realloc(tc, size + TC_HDR_SIZE);
798 if (unlikely(!new_ptr)) {
799 tc->flags &= ~TALLOC_FLAG_FREE;
803 tc = (struct talloc_chunk *)new_ptr;
804 tc->flags &= ~TALLOC_FLAG_FREE;
806 tc->parent->child = tc;
809 tc->child->parent = tc;
820 _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
822 return TC_PTR_FROM_CHUNK(tc);
826 a wrapper around talloc_steal() for situations where you are moving a pointer
827 between two structures, and want the old pointer to be set to NULL
829 void *_talloc_move(const void *new_ctx, const void *_pptr)
831 const void **pptr = discard_const_p(const void *,_pptr);
832 void *ret = _talloc_steal(new_ctx, *pptr);
838 return the total size of a talloc pool (subtree)
840 size_t talloc_total_size(const void *ptr)
843 struct talloc_chunk *c, *tc;
852 tc = talloc_chunk_from_ptr(ptr);
854 if (tc->flags & TALLOC_FLAG_LOOP) {
858 tc->flags |= TALLOC_FLAG_LOOP;
861 for (c=tc->child;c;c=c->next) {
862 total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
865 tc->flags &= ~TALLOC_FLAG_LOOP;
871 return the total number of blocks in a talloc pool (subtree)
873 size_t talloc_total_blocks(const void *ptr)
876 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
878 if (tc->flags & TALLOC_FLAG_LOOP) {
882 tc->flags |= TALLOC_FLAG_LOOP;
885 for (c=tc->child;c;c=c->next) {
886 total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
889 tc->flags &= ~TALLOC_FLAG_LOOP;
895 return the number of external references to a pointer
897 size_t talloc_reference_count(const void *ptr)
899 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
900 struct talloc_reference_handle *h;
903 for (h=tc->refs;h;h=h->next) {
910 report on memory usage by all children of a pointer, giving a full tree view
912 void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
913 void (*callback)(const void *ptr,
914 int depth, int max_depth,
919 struct talloc_chunk *c, *tc;
924 if (ptr == NULL) return;
926 tc = talloc_chunk_from_ptr(ptr);
928 if (tc->flags & TALLOC_FLAG_LOOP) {
932 callback(ptr, depth, max_depth, 0, private_data);
934 if (max_depth >= 0 && depth >= max_depth) {
938 tc->flags |= TALLOC_FLAG_LOOP;
939 for (c=tc->child;c;c=c->next) {
940 if (c->name == TALLOC_MAGIC_REFERENCE) {
941 struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
942 callback(h->ptr, depth + 1, max_depth, 1, private_data);
944 talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
947 tc->flags &= ~TALLOC_FLAG_LOOP;
950 static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
952 const char *name = talloc_get_name(ptr);
953 FILE *f = (FILE *)_f;
956 fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
961 fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n",
962 (max_depth < 0 ? "full " :""), name,
963 (unsigned long)talloc_total_size(ptr),
964 (unsigned long)talloc_total_blocks(ptr));
968 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n",
971 (unsigned long)talloc_total_size(ptr),
972 (unsigned long)talloc_total_blocks(ptr),
973 (int)talloc_reference_count(ptr), ptr);
976 fprintf(f, "content: ");
977 if (talloc_total_size(ptr)) {
978 int tot = talloc_total_size(ptr);
981 for (i = 0; i < tot; i++) {
982 if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
983 fprintf(f, "%c", ((char *)ptr)[i]);
985 fprintf(f, "~%02x", ((char *)ptr)[i]);
994 report on memory usage by all children of a pointer, giving a full tree view
996 void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
998 talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
1003 report on memory usage by all children of a pointer, giving a full tree view
1005 void talloc_report_full(const void *ptr, FILE *f)
1007 talloc_report_depth_file(ptr, 0, -1, f);
1011 report on memory usage by all children of a pointer
1013 void talloc_report(const void *ptr, FILE *f)
1015 talloc_report_depth_file(ptr, 0, 1, f);
1019 report on any memory hanging off the null context
1021 static void talloc_report_null(void)
1023 if (talloc_total_size(null_context) != 0) {
1024 talloc_report(null_context, stderr);
1029 report on any memory hanging off the null context
1031 static void talloc_report_null_full(void)
1033 if (talloc_total_size(null_context) != 0) {
1034 talloc_report_full(null_context, stderr);
1039 enable tracking of the NULL context
1041 void talloc_enable_null_tracking(void)
1043 if (null_context == NULL) {
1044 null_context = _talloc_named_const(NULL, 0, "null_context");
1049 disable tracking of the NULL context
1051 void talloc_disable_null_tracking(void)
1053 _talloc_free(null_context);
1054 null_context = NULL;
1058 enable leak reporting on exit
1060 void talloc_enable_leak_report(void)
1062 talloc_enable_null_tracking();
1063 atexit(talloc_report_null);
1067 enable full leak reporting on exit
1069 void talloc_enable_leak_report_full(void)
1071 talloc_enable_null_tracking();
1072 atexit(talloc_report_null_full);
1076 talloc and zero memory.
1078 void *_talloc_zero(const void *ctx, size_t size, const char *name)
1080 void *p = _talloc_named_const(ctx, size, name);
1083 memset(p, '\0', size);
1090 memdup with a talloc.
1092 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
1094 void *newp = _talloc_named_const(t, size, name);
1097 memcpy(newp, p, size);
1104 strdup with a talloc
1106 char *talloc_strdup(const void *t, const char *p)
1112 ret = (char *)talloc_memdup(t, p, strlen(p) + 1);
1114 _talloc_set_name_const(ret, ret);
1120 append to a talloced string
1122 char *talloc_append_string(const void *t, char *orig, const char *append)
1125 size_t olen = strlen(orig);
1131 alenz = strlen(append) + 1;
1133 ret = talloc_realloc(t, orig, char, olen + alenz);
1137 /* append the string with the trailing \0 */
1138 memcpy(&ret[olen], append, alenz);
1140 _talloc_set_name_const(ret, ret);
1146 strndup with a talloc
1148 char *talloc_strndup(const void *t, const char *p, size_t n)
1153 for (len=0; len<n && p[len]; len++) ;
1155 ret = (char *)__talloc(t, len + 1);
1156 if (!ret) { return NULL; }
1157 memcpy(ret, p, len);
1159 _talloc_set_name_const(ret, ret);
1163 #ifndef HAVE_VA_COPY
1164 #ifdef HAVE___VA_COPY
1165 #define va_copy(dest, src) __va_copy(dest, src)
1167 #define va_copy(dest, src) (dest) = (src)
1171 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1178 /* this call looks strange, but it makes it work on older solaris boxes */
1180 len = vsnprintf(&c, 1, fmt, ap2);
1186 ret = (char *)__talloc(t, len+1);
1189 vsnprintf(ret, len+1, fmt, ap2);
1191 _talloc_set_name_const(ret, ret);
1199 Perform string formatting, and return a pointer to newly allocated
1200 memory holding the result, inside a memory pool.
1202 char *talloc_asprintf(const void *t, const char *fmt, ...)
1208 ret = talloc_vasprintf(t, fmt, ap);
1215 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1216 * and return @p s, which may have moved. Good for gradually
1217 * accumulating output into a string buffer.
1219 char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1221 struct talloc_chunk *tc;
1227 return talloc_vasprintf(NULL, fmt, ap);
1230 tc = talloc_chunk_from_ptr(s);
1232 s_len = tc->size - 1;
1235 len = vsnprintf(&c, 1, fmt, ap2);
1239 /* Either the vsnprintf failed or the format resulted in
1240 * no characters being formatted. In the former case, we
1241 * ought to return NULL, in the latter we ought to return
1242 * the original string. Most current callers of this
1243 * function expect it to never return NULL.
1248 s = talloc_realloc(NULL, s, char, s_len + len+1);
1249 if (!s) return NULL;
1252 vsnprintf(s+s_len, len+1, fmt, ap2);
1254 _talloc_set_name_const(s, s);
1260 Realloc @p s to append the formatted result of @p fmt and return @p
1261 s, which may have moved. Good for gradually accumulating output
1262 into a string buffer.
1264 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1269 s = talloc_vasprintf_append(s, fmt, ap);
1275 alloc an array, checking for integer overflow in the array size
1277 void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1279 if (count >= MAX_TALLOC_SIZE/el_size) {
1282 return _talloc_named_const(ctx, el_size * count, name);
1286 alloc an zero array, checking for integer overflow in the array size
1288 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1290 if (count >= MAX_TALLOC_SIZE/el_size) {
1293 return _talloc_zero(ctx, el_size * count, name);
1297 realloc an array, checking for integer overflow in the array size
1299 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1301 if (count >= MAX_TALLOC_SIZE/el_size) {
1304 return _talloc_realloc(ctx, ptr, el_size * count, name);
1308 a function version of talloc_realloc(), so it can be passed as a function pointer
1309 to libraries that want a realloc function (a realloc function encapsulates
1310 all the basic capabilities of an allocation library, which is why this is useful)
1312 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1314 return _talloc_realloc(context, ptr, size, NULL);
1318 static int talloc_autofree_destructor(void *ptr)
1320 autofree_context = NULL;
1324 static void talloc_autofree(void)
1326 _talloc_free(autofree_context);
1330 return a context which will be auto-freed on exit
1331 this is useful for reducing the noise in leak reports
1333 void *talloc_autofree_context(void)
1335 if (autofree_context == NULL) {
1336 autofree_context = _talloc_named_const(NULL, 0, "autofree_context");
1337 talloc_set_destructor(autofree_context, talloc_autofree_destructor);
1338 atexit(talloc_autofree);
1340 return autofree_context;
1343 size_t talloc_get_size(const void *context)
1345 struct talloc_chunk *tc;
1347 if (context == NULL)
1350 tc = talloc_chunk_from_ptr(context);
1356 find a parent of this context that has the given name, if any
1358 void *talloc_find_parent_byname(const void *context, const char *name)
1360 struct talloc_chunk *tc;
1362 if (context == NULL) {
1366 tc = talloc_chunk_from_ptr(context);
1368 if (tc->name && strcmp(tc->name, name) == 0) {
1369 return TC_PTR_FROM_CHUNK(tc);
1371 while (tc && tc->prev) tc = tc->prev;
1380 show the parentage of a context
1382 void talloc_show_parents(const void *context, FILE *file)
1384 struct talloc_chunk *tc;
1386 if (context == NULL) {
1387 fprintf(file, "talloc no parents for NULL\n");
1391 tc = talloc_chunk_from_ptr(context);
1392 fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
1394 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
1395 while (tc && tc->prev) tc = tc->prev;
1404 return 1 if ptr is a parent of context
1406 int talloc_is_parent(const void *context, const void *ptr)
1408 struct talloc_chunk *tc;
1410 if (context == NULL) {
1414 tc = talloc_chunk_from_ptr(context);
1416 if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
1417 while (tc && tc->prev) tc = tc->prev;