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
10 ** NOTE! The following LGPL license applies to the talloc
11 ** library. This does NOT imply that all of Samba is released
14 This library is free software; you can redistribute it and/or
15 modify it under the terms of the GNU Lesser General Public
16 License as published by the Free Software Foundation; either
17 version 2 of the License, or (at your option) any later version.
19 This library is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 Lesser General Public License for more details.
24 You should have received a copy of the GNU Lesser General Public
25 License along with this library; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 inspired by http://swapped.cc/halloc/
43 #if defined(HAVE_STDARG_H)
45 #elif defined (HAVE_VARARGS_H)
48 #error "no var arg header"
53 /* use this to force every realloc to change the pointer, to stress test
54 code that might not cope */
55 #define ALWAYS_REALLOC 0
58 #define MAX_TALLOC_SIZE 0x10000000
59 #define TALLOC_MAGIC 0xe814ec70
60 #define TALLOC_FLAG_FREE 0x01
61 #define TALLOC_FLAG_LOOP 0x02
62 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
64 /* by default we abort when given a bad pointer (such as when talloc_free() is called
65 on a pointer that came from malloc() */
67 #define TALLOC_ABORT(reason) abort()
70 #ifndef discard_const_p
71 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
72 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
74 # define discard_const_p(type, ptr) ((type *)(ptr))
78 /* this null_context is only used if talloc_enable_leak_report() or
79 talloc_enable_leak_report_full() is called, otherwise it remains
82 static void *null_context;
83 static void *cleanup_context;
85 struct talloc_reference_handle {
86 struct talloc_reference_handle *next, *prev;
90 typedef int (*talloc_destructor_t)(void *);
93 struct talloc_chunk *next, *prev;
94 struct talloc_chunk *parent, *child;
95 struct talloc_reference_handle *refs;
96 talloc_destructor_t destructor;
102 /* 16 byte alignment seems to keep everyone happy */
103 #define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
104 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
106 /* panic if we get a bad magic value */
107 static struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
109 const char *pp = (const char *)ptr;
110 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
111 if ((tc->flags & ~0xF) != TALLOC_MAGIC) {
112 TALLOC_ABORT("Bad talloc magic value - unknown value");
114 if (tc->flags & TALLOC_FLAG_FREE) {
115 TALLOC_ABORT("Bad talloc magic value - double free");
120 /* hook into the front of the list */
121 #define _TLIST_ADD(list, p) \
125 (p)->next = (p)->prev = NULL; \
127 (list)->prev = (p); \
128 (p)->next = (list); \
134 /* remove an element from a list - element doesn't have to be in list. */
135 #define _TLIST_REMOVE(list, p) \
137 if ((p) == (list)) { \
138 (list) = (p)->next; \
139 if (list) (list)->prev = NULL; \
141 if ((p)->prev) (p)->prev->next = (p)->next; \
142 if ((p)->next) (p)->next->prev = (p)->prev; \
144 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
149 return the parent chunk of a pointer
151 static struct talloc_chunk *talloc_parent_chunk(const void *ptr)
153 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
154 while (tc->prev) tc=tc->prev;
158 void *talloc_parent(const void *ptr)
160 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
161 return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
165 Allocate a bit of memory as a child of an existing pointer
167 void *_talloc(const void *context, size_t size)
169 struct talloc_chunk *tc;
171 if (context == NULL) {
172 context = null_context;
175 if (size >= MAX_TALLOC_SIZE) {
179 tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size);
180 if (tc == NULL) return NULL;
183 tc->flags = TALLOC_MAGIC;
184 tc->destructor = NULL;
190 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
195 parent->child->parent = NULL;
198 _TLIST_ADD(parent->child, tc);
200 tc->next = tc->prev = tc->parent = NULL;
203 return TC_PTR_FROM_CHUNK(tc);
208 setup a destructor to be called on free of a pointer
209 the destructor should return 0 on success, or -1 on failure.
210 if the destructor fails then the free is failed, and the memory can
211 be continued to be used
213 void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
215 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
216 tc->destructor = destructor;
220 increase the reference count on a piece of memory.
222 void talloc_increase_ref_count(const void *ptr)
224 talloc_reference(null_context, ptr);
228 helper for talloc_reference()
230 static int talloc_reference_destructor(struct talloc_reference_handle *handle)
232 struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
233 _TLIST_REMOVE(ptr_tc->refs, handle);
238 make a secondary reference to a pointer, hanging off the given context.
239 the pointer remains valid until both the original caller and this given
242 the major use for this is when two different structures need to reference the
243 same underlying data, and you want to be able to free the two instances separately,
246 void *talloc_reference(const void *context, const void *ptr)
248 struct talloc_chunk *tc;
249 struct talloc_reference_handle *handle;
250 if (ptr == NULL) return NULL;
252 tc = talloc_chunk_from_ptr(ptr);
253 handle = (struct talloc_reference_handle *)talloc_named_const(context,
254 sizeof(struct talloc_reference_handle),
255 TALLOC_MAGIC_REFERENCE);
256 if (handle == NULL) return NULL;
258 /* note that we hang the destructor off the handle, not the
259 main context as that allows the caller to still setup their
260 own destructor on the context if they want to */
261 talloc_set_destructor(handle, talloc_reference_destructor);
262 handle->ptr = discard_const_p(void, ptr);
263 _TLIST_ADD(tc->refs, handle);
268 remove a secondary reference to a pointer. This undo's what
269 talloc_reference() has done. The context and pointer arguments
270 must match those given to a talloc_reference()
272 static int talloc_unreference(const void *context, const void *ptr)
274 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
275 struct talloc_reference_handle *h;
277 if (context == NULL) {
278 context = null_context;
281 for (h=tc->refs;h;h=h->next) {
282 struct talloc_chunk *p = talloc_parent_chunk(h);
284 if (context == NULL) break;
285 } else if (TC_PTR_FROM_CHUNK(p) == context) {
293 return talloc_free(h);
297 remove a specific parent context from a pointer. This is a more
298 controlled varient of talloc_free()
300 int talloc_unlink(const void *context, void *ptr)
302 struct talloc_chunk *tc_p, *new_p;
309 if (context == NULL) {
310 context = null_context;
313 if (talloc_unreference(context, ptr) == 0) {
317 if (context == NULL) {
318 if (talloc_parent_chunk(ptr) != NULL) {
322 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
327 tc_p = talloc_chunk_from_ptr(ptr);
329 if (tc_p->refs == NULL) {
330 return talloc_free(ptr);
333 new_p = talloc_parent_chunk(tc_p->refs);
335 new_parent = TC_PTR_FROM_CHUNK(new_p);
340 if (talloc_unreference(new_parent, ptr) != 0) {
344 talloc_steal(new_parent, ptr);
350 add a name to an existing pointer - va_list version
352 static const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
354 static const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
356 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
357 tc->name = talloc_vasprintf(ptr, fmt, ap);
359 talloc_set_name_const(tc->name, ".name");
365 add a name to an existing pointer
367 const char *talloc_set_name(const void *ptr, const char *fmt, ...)
372 name = talloc_set_name_v(ptr, fmt, ap);
378 more efficient way to add a name to a pointer - the name must point to a
381 void talloc_set_name_const(const void *ptr, const char *name)
383 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
388 create a named talloc pointer. Any talloc pointer can be named, and
389 talloc_named() operates just like talloc() except that it allows you
392 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
398 ptr = _talloc(context, size);
399 if (ptr == NULL) return NULL;
402 name = talloc_set_name_v(ptr, fmt, ap);
414 create a named talloc pointer. Any talloc pointer can be named, and
415 talloc_named() operates just like talloc() except that it allows you
418 void *talloc_named_const(const void *context, size_t size, const char *name)
422 ptr = _talloc(context, size);
427 talloc_set_name_const(ptr, name);
433 return the name of a talloc ptr, or "UNNAMED"
435 const char *talloc_get_name(const void *ptr)
437 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
438 if (tc->name == TALLOC_MAGIC_REFERENCE) {
449 check if a pointer has the given name. If it does, return the pointer,
450 otherwise return NULL
452 void *talloc_check_name(const void *ptr, const char *name)
455 if (ptr == NULL) return NULL;
456 pname = talloc_get_name(ptr);
457 if (pname == name || strcmp(pname, name) == 0) {
458 return discard_const_p(void, ptr);
465 this is for compatibility with older versions of talloc
467 void *talloc_init(const char *fmt, ...)
473 ptr = _talloc(NULL, 0);
474 if (ptr == NULL) return NULL;
477 name = talloc_set_name_v(ptr, fmt, ap);
489 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
490 should probably not be used in new code. It's in here to keep the talloc
491 code consistent across Samba 3 and 4.
493 void talloc_free_children(void *ptr)
495 struct talloc_chunk *tc;
501 tc = talloc_chunk_from_ptr(ptr);
504 /* we need to work out who will own an abandoned child
505 if it cannot be freed. In priority order, the first
506 choice is owner of any remaining reference to this
507 pointer, the second choice is our parent, and the
508 final choice is the null context. */
509 void *child = TC_PTR_FROM_CHUNK(tc->child);
510 const void *new_parent = null_context;
511 if (tc->child->refs) {
512 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
513 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
515 if (talloc_free(child) == -1) {
516 if (new_parent == null_context) {
517 struct talloc_chunk *p = talloc_parent_chunk(ptr);
518 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
520 talloc_steal(new_parent, child);
526 free a talloc pointer. This also frees all child pointers of this
529 return 0 if the memory is actually freed, otherwise -1. The memory
530 will not be freed if the ref_count is > 1 or the destructor (if
531 any) returns non-zero
533 int talloc_free(void *ptr)
535 struct talloc_chunk *tc;
542 tc = talloc_chunk_from_ptr(ptr);
546 /* check this is a reference from a child or grantchild
547 * back to it's parent or grantparent
549 * in that case we need to remove the reference and
550 * call another instance of talloc_free() on the current
553 is_child = talloc_is_parent(tc->refs, ptr);
554 talloc_free(tc->refs);
556 return talloc_free(ptr);
561 if (tc->flags & TALLOC_FLAG_LOOP) {
562 /* we have a free loop - stop looping */
566 if (tc->destructor) {
567 talloc_destructor_t d = tc->destructor;
568 if (d == (talloc_destructor_t)-1) {
571 tc->destructor = (talloc_destructor_t)-1;
576 tc->destructor = NULL;
580 _TLIST_REMOVE(tc->parent->child, tc);
581 if (tc->parent->child) {
582 tc->parent->child->parent = tc->parent;
585 if (tc->prev) tc->prev->next = tc->next;
586 if (tc->next) tc->next->prev = tc->prev;
589 tc->flags |= TALLOC_FLAG_LOOP;
590 talloc_free_children(ptr);
592 tc->flags |= TALLOC_FLAG_FREE;
602 A talloc version of realloc. The context argument is only used if
605 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
607 struct talloc_chunk *tc;
610 /* size zero is equivalent to free() */
616 if (size >= MAX_TALLOC_SIZE) {
620 /* realloc(NULL) is equavalent to malloc() */
622 return talloc_named_const(context, size, name);
625 tc = talloc_chunk_from_ptr(ptr);
627 /* don't allow realloc on referenced pointers */
632 /* by resetting magic we catch users of the old memory */
633 tc->flags |= TALLOC_FLAG_FREE;
636 new_ptr = malloc(size + TC_HDR_SIZE);
638 memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
642 new_ptr = realloc(tc, size + TC_HDR_SIZE);
645 tc->flags &= ~TALLOC_FLAG_FREE;
649 tc = (struct talloc_chunk *)new_ptr;
650 tc->flags &= ~TALLOC_FLAG_FREE;
652 tc->parent->child = tc;
655 tc->child->parent = tc;
666 talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
668 return TC_PTR_FROM_CHUNK(tc);
672 move a lump of memory from one talloc context to another return the
673 ptr on success, or NULL if it could not be transferred.
674 passing NULL as ptr will always return NULL with no side effects.
676 void *_talloc_steal(const void *new_ctx, const void *ptr)
678 struct talloc_chunk *tc, *new_tc;
684 if (new_ctx == NULL) {
685 new_ctx = null_context;
688 tc = talloc_chunk_from_ptr(ptr);
690 if (new_ctx == NULL) {
692 _TLIST_REMOVE(tc->parent->child, tc);
693 if (tc->parent->child) {
694 tc->parent->child->parent = tc->parent;
697 if (tc->prev) tc->prev->next = tc->next;
698 if (tc->next) tc->next->prev = tc->prev;
701 tc->parent = tc->next = tc->prev = NULL;
702 return discard_const_p(void, ptr);
705 new_tc = talloc_chunk_from_ptr(new_ctx);
707 if (tc == new_tc || tc->parent == new_tc) {
708 return discard_const_p(void, ptr);
712 _TLIST_REMOVE(tc->parent->child, tc);
713 if (tc->parent->child) {
714 tc->parent->child->parent = tc->parent;
717 if (tc->prev) tc->prev->next = tc->next;
718 if (tc->next) tc->next->prev = tc->prev;
722 if (new_tc->child) new_tc->child->parent = NULL;
723 _TLIST_ADD(new_tc->child, tc);
725 return discard_const_p(void, ptr);
729 return the total size of a talloc pool (subtree)
731 size_t talloc_total_size(const void *ptr)
734 struct talloc_chunk *c, *tc;
743 tc = talloc_chunk_from_ptr(ptr);
745 if (tc->flags & TALLOC_FLAG_LOOP) {
749 tc->flags |= TALLOC_FLAG_LOOP;
752 for (c=tc->child;c;c=c->next) {
753 total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
756 tc->flags &= ~TALLOC_FLAG_LOOP;
762 return the total number of blocks in a talloc pool (subtree)
764 size_t talloc_total_blocks(const void *ptr)
767 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
769 if (tc->flags & TALLOC_FLAG_LOOP) {
773 tc->flags |= TALLOC_FLAG_LOOP;
776 for (c=tc->child;c;c=c->next) {
777 total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
780 tc->flags &= ~TALLOC_FLAG_LOOP;
786 return the number of external references to a pointer
788 static int talloc_reference_count(const void *ptr)
790 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
791 struct talloc_reference_handle *h;
794 for (h=tc->refs;h;h=h->next) {
801 report on memory usage by all children of a pointer, giving a full tree view
803 void talloc_report_depth(const void *ptr, FILE *f, int depth)
805 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
807 if (tc->flags & TALLOC_FLAG_LOOP) {
811 tc->flags |= TALLOC_FLAG_LOOP;
813 for (c=tc->child;c;c=c->next) {
814 if (c->name == TALLOC_MAGIC_REFERENCE) {
815 struct talloc_reference_handle *handle =
816 (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
817 const char *name2 = talloc_get_name(handle->ptr);
818 fprintf(f, "%*sreference to: %s\n", depth*4, "", name2);
820 const char *name = talloc_get_name(TC_PTR_FROM_CHUNK(c));
821 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n",
824 (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c)),
825 (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)),
826 talloc_reference_count(TC_PTR_FROM_CHUNK(c)));
827 talloc_report_depth(TC_PTR_FROM_CHUNK(c), f, depth+1);
830 tc->flags &= ~TALLOC_FLAG_LOOP;
834 report on memory usage by all children of a pointer, giving a full tree view
836 void talloc_report_full(const void *ptr, FILE *f)
841 if (ptr == NULL) return;
843 fprintf(f,"full talloc report on '%s' (total %lu bytes in %lu blocks)\n",
844 talloc_get_name(ptr),
845 (unsigned long)talloc_total_size(ptr),
846 (unsigned long)talloc_total_blocks(ptr));
848 talloc_report_depth(ptr, f, 1);
853 report on memory usage by all children of a pointer
855 void talloc_report(const void *ptr, FILE *f)
857 struct talloc_chunk *c, *tc;
862 if (ptr == NULL) return;
864 fprintf(f,"talloc report on '%s' (total %lu bytes in %lu blocks)\n",
865 talloc_get_name(ptr),
866 (unsigned long)talloc_total_size(ptr),
867 (unsigned long)talloc_total_blocks(ptr));
869 tc = talloc_chunk_from_ptr(ptr);
871 for (c=tc->child;c;c=c->next) {
872 fprintf(f, "\t%-30s contains %6lu bytes in %3lu blocks\n",
873 talloc_get_name(TC_PTR_FROM_CHUNK(c)),
874 (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c)),
875 (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)));
881 report on any memory hanging off the null context
883 static void talloc_report_null(void)
885 if (talloc_total_size(null_context) != 0) {
886 talloc_report(null_context, stderr);
891 report on any memory hanging off the null context
893 static void talloc_report_null_full(void)
895 if (talloc_total_size(null_context) != 0) {
896 talloc_report_full(null_context, stderr);
901 enable tracking of the NULL context
903 void talloc_enable_null_tracking(void)
905 if (null_context == NULL) {
906 null_context = talloc_named_const(NULL, 0, "null_context");
911 disable tracking of the NULL context
913 void talloc_disable_null_tracking(void)
915 talloc_free(null_context);
920 enable leak reporting on exit
922 void talloc_enable_leak_report(void)
924 talloc_enable_null_tracking();
925 atexit(talloc_report_null);
929 enable full leak reporting on exit
931 void talloc_enable_leak_report_full(void)
933 talloc_enable_null_tracking();
934 atexit(talloc_report_null_full);
938 talloc and zero memory.
940 void *_talloc_zero(const void *ctx, size_t size, const char *name)
942 void *p = talloc_named_const(ctx, size, name);
945 memset(p, '\0', size);
953 memdup with a talloc.
955 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
957 void *newp = talloc_named_const(t, size, name);
960 memcpy(newp, p, size);
969 char *talloc_strdup(const void *t, const char *p)
975 ret = (char *)talloc_memdup(t, p, strlen(p) + 1);
977 talloc_set_name_const(ret, ret);
983 append to a talloced string
985 char *talloc_append_string(const void *t, char *orig, const char *append)
988 size_t olen = strlen(orig);
994 alenz = strlen(append) + 1;
996 ret = talloc_realloc(t, orig, char, olen + alenz);
1000 /* append the string with the trailing \0 */
1001 memcpy(&ret[olen], append, alenz);
1007 strndup with a talloc
1009 char *talloc_strndup(const void *t, const char *p, size_t n)
1014 for (len=0; len<n && p[len]; len++) ;
1016 ret = (char *)_talloc(t, len + 1);
1017 if (!ret) { return NULL; }
1018 memcpy(ret, p, len);
1020 talloc_set_name_const(ret, ret);
1024 #ifndef HAVE_VA_COPY
1025 #ifdef HAVE___VA_COPY
1026 #define va_copy(dest, src) __va_copy(dest, src)
1028 #define va_copy(dest, src) (dest) = (src)
1032 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1041 /* this call looks strange, but it makes it work on older solaris boxes */
1042 if ((len = vsnprintf(&c, 1, fmt, ap2)) < 0) {
1046 ret = (char *)_talloc(t, len+1);
1049 vsnprintf(ret, len+1, fmt, ap2);
1050 talloc_set_name_const(ret, ret);
1058 Perform string formatting, and return a pointer to newly allocated
1059 memory holding the result, inside a memory pool.
1061 char *talloc_asprintf(const void *t, const char *fmt, ...)
1067 ret = talloc_vasprintf(t, fmt, ap);
1074 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1075 * and return @p s, which may have moved. Good for gradually
1076 * accumulating output into a string buffer.
1078 char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1080 struct talloc_chunk *tc;
1086 return talloc_vasprintf(NULL, fmt, ap);
1089 tc = talloc_chunk_from_ptr(s);
1093 s_len = tc->size - 1;
1094 if ((len = vsnprintf(&c, 1, fmt, ap2)) <= 0) {
1095 /* Either the vsnprintf failed or the format resulted in
1096 * no characters being formatted. In the former case, we
1097 * ought to return NULL, in the latter we ought to return
1098 * the original string. Most current callers of this
1099 * function expect it to never return NULL.
1104 s = talloc_realloc(NULL, s, char, s_len + len+1);
1105 if (!s) return NULL;
1109 vsnprintf(s+s_len, len+1, fmt, ap2);
1110 talloc_set_name_const(s, s);
1116 Realloc @p s to append the formatted result of @p fmt and return @p
1117 s, which may have moved. Good for gradually accumulating output
1118 into a string buffer.
1120 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1125 s = talloc_vasprintf_append(s, fmt, ap);
1131 alloc an array, checking for integer overflow in the array size
1133 void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1135 if (count >= MAX_TALLOC_SIZE/el_size) {
1138 return talloc_named_const(ctx, el_size * count, name);
1142 alloc an zero array, checking for integer overflow in the array size
1144 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1146 if (count >= MAX_TALLOC_SIZE/el_size) {
1149 return _talloc_zero(ctx, el_size * count, name);
1154 realloc an array, checking for integer overflow in the array size
1156 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1158 if (count >= MAX_TALLOC_SIZE/el_size) {
1161 return _talloc_realloc(ctx, ptr, el_size * count, name);
1165 a function version of talloc_realloc(), so it can be passed as a function pointer
1166 to libraries that want a realloc function (a realloc function encapsulates
1167 all the basic capabilities of an allocation library, which is why this is useful)
1169 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1171 return _talloc_realloc(context, ptr, size, NULL);
1175 static void talloc_autofree(void)
1177 talloc_free(cleanup_context);
1178 cleanup_context = NULL;
1182 return a context which will be auto-freed on exit
1183 this is useful for reducing the noise in leak reports
1185 void *talloc_autofree_context(void)
1187 if (cleanup_context == NULL) {
1188 cleanup_context = talloc_named_const(NULL, 0, "autofree_context");
1189 atexit(talloc_autofree);
1191 return cleanup_context;
1194 size_t talloc_get_size(const void *context)
1196 struct talloc_chunk *tc;
1198 if (context == NULL)
1201 tc = talloc_chunk_from_ptr(context);
1207 find a parent of this context that has the given name, if any
1209 void *talloc_find_parent_byname(const void *context, const char *name)
1211 struct talloc_chunk *tc;
1213 if (context == NULL) {
1217 tc = talloc_chunk_from_ptr(context);
1219 if (tc->name && strcmp(tc->name, name) == 0) {
1220 return TC_PTR_FROM_CHUNK(tc);
1222 while (tc && tc->prev) tc = tc->prev;
1231 show the parentage of a context
1233 void talloc_show_parents(const void *context, FILE *file)
1235 struct talloc_chunk *tc;
1237 if (context == NULL) {
1238 fprintf(file, "talloc no parents for NULL\n");
1242 tc = talloc_chunk_from_ptr(context);
1243 fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
1245 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
1246 while (tc && tc->prev) tc = tc->prev;
1254 return 1 if ptr is a parent of context
1256 int talloc_is_parent(const void *context, const void *ptr)
1258 struct talloc_chunk *tc;
1260 if (context == NULL) {
1264 tc = talloc_chunk_from_ptr(context);
1266 if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
1267 while (tc && tc->prev) tc = tc->prev;