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/
40 #ifdef HAVE_SYS_TYPES_H
41 #include <sys/types.h>
60 /* use this to force every realloc to change the pointer, to stress test
61 code that might not cope */
62 #define ALWAYS_REALLOC 0
65 #define MAX_TALLOC_SIZE 0x10000000
66 #define TALLOC_MAGIC 0xe814ec70
67 #define TALLOC_FLAG_FREE 0x01
68 #define TALLOC_FLAG_LOOP 0x02
69 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
71 /* by default we abort when given a bad pointer (such as when talloc_free() is called
72 on a pointer that came from malloc() */
74 #define TALLOC_ABORT(reason) abort()
77 #ifndef discard_const_p
78 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
79 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
81 # define discard_const_p(type, ptr) ((type *)(ptr))
85 /* this null_context is only used if talloc_enable_leak_report() or
86 talloc_enable_leak_report_full() is called, otherwise it remains
89 static const void *null_context;
90 static void *cleanup_context;
93 struct talloc_reference_handle {
94 struct talloc_reference_handle *next, *prev;
98 typedef int (*talloc_destructor_t)(void *);
100 struct talloc_chunk {
101 struct talloc_chunk *next, *prev;
102 struct talloc_chunk *parent, *child;
103 struct talloc_reference_handle *refs;
104 talloc_destructor_t destructor;
110 /* 16 byte alignment seems to keep everyone happy */
111 #define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
112 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
114 /* panic if we get a bad magic value */
115 static struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
117 const char *pp = ptr;
118 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
119 if ((tc->flags & ~0xF) != TALLOC_MAGIC) {
120 TALLOC_ABORT("Bad talloc magic value - unknown value");
122 if (tc->flags & TALLOC_FLAG_FREE) {
123 TALLOC_ABORT("Bad talloc magic value - double free");
128 /* hook into the front of the list */
129 #define _TLIST_ADD(list, p) \
133 (p)->next = (p)->prev = NULL; \
135 (list)->prev = (p); \
136 (p)->next = (list); \
142 /* remove an element from a list - element doesn't have to be in list. */
143 #define _TLIST_REMOVE(list, p) \
145 if ((p) == (list)) { \
146 (list) = (p)->next; \
147 if (list) (list)->prev = NULL; \
149 if ((p)->prev) (p)->prev->next = (p)->next; \
150 if ((p)->next) (p)->next->prev = (p)->prev; \
152 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
157 return the parent chunk of a pointer
159 static struct talloc_chunk *talloc_parent_chunk(const void *ptr)
161 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
162 while (tc->prev) tc=tc->prev;
166 void *talloc_parent(const void *ptr)
168 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
169 return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
173 Allocate a bit of memory as a child of an existing pointer
175 void *_talloc(const void *context, size_t size)
177 struct talloc_chunk *tc;
179 if (context == NULL) {
180 context = null_context;
183 if (size >= MAX_TALLOC_SIZE) {
187 tc = malloc(TC_HDR_SIZE+size);
188 if (tc == NULL) return NULL;
191 tc->flags = TALLOC_MAGIC;
192 tc->destructor = NULL;
198 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
203 parent->child->parent = NULL;
206 _TLIST_ADD(parent->child, tc);
208 tc->next = tc->prev = tc->parent = NULL;
211 return TC_PTR_FROM_CHUNK(tc);
216 setup a destructor to be called on free of a pointer
217 the destructor should return 0 on success, or -1 on failure.
218 if the destructor fails then the free is failed, and the memory can
219 be continued to be used
221 void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
223 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
224 tc->destructor = destructor;
228 increase the reference count on a piece of memory.
230 void talloc_increase_ref_count(const void *ptr)
232 talloc_reference(null_context, ptr);
236 helper for talloc_reference()
238 static int talloc_reference_destructor(struct talloc_reference_handle *handle)
240 struct talloc_chunk *tc1 = talloc_chunk_from_ptr(handle);
241 struct talloc_chunk *tc2 = talloc_chunk_from_ptr(handle->ptr);
242 if (tc1->destructor != (talloc_destructor_t)-1) {
243 tc1->destructor = NULL;
245 _TLIST_REMOVE(tc2->refs, handle);
251 make a secondary reference to a pointer, hanging off the given context.
252 the pointer remains valid until both the original caller and this given
255 the major use for this is when two different structures need to reference the
256 same underlying data, and you want to be able to free the two instances separately,
259 void *talloc_reference(const void *context, const void *ptr)
261 struct talloc_chunk *tc;
262 struct talloc_reference_handle *handle;
263 if (ptr == NULL) return NULL;
265 tc = talloc_chunk_from_ptr(ptr);
266 handle = talloc_named_const(context, sizeof(*handle), TALLOC_MAGIC_REFERENCE);
268 if (handle == NULL) return NULL;
270 /* note that we hang the destructor off the handle, not the
271 main context as that allows the caller to still setup their
272 own destructor on the context if they want to */
273 talloc_set_destructor(handle, talloc_reference_destructor);
274 handle->ptr = discard_const_p(void, ptr);
275 _TLIST_ADD(tc->refs, handle);
280 remove a secondary reference to a pointer. This undo's what
281 talloc_reference() has done. The context and pointer arguments
282 must match those given to a talloc_reference()
284 static int talloc_unreference(const void *context, const void *ptr)
286 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
287 struct talloc_reference_handle *h;
289 if (context == NULL) {
290 context = null_context;
293 for (h=tc->refs;h;h=h->next) {
294 struct talloc_chunk *p = talloc_parent_chunk(h);
296 if (context == NULL) break;
297 } else if (TC_PTR_FROM_CHUNK(p) == context) {
305 talloc_set_destructor(h, NULL);
306 _TLIST_REMOVE(tc->refs, h);
312 remove a specific parent context from a pointer. This is a more
313 controlled varient of talloc_free()
315 int talloc_unlink(const void *context, void *ptr)
317 struct talloc_chunk *tc_p, *new_p;
324 if (context == NULL) {
325 context = null_context;
328 if (talloc_unreference(context, ptr) == 0) {
332 if (context == NULL) {
333 if (talloc_parent_chunk(ptr) != NULL) {
337 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
342 tc_p = talloc_chunk_from_ptr(ptr);
344 if (tc_p->refs == NULL) {
345 return talloc_free(ptr);
348 new_p = talloc_parent_chunk(tc_p->refs);
350 new_parent = TC_PTR_FROM_CHUNK(new_p);
355 if (talloc_unreference(new_parent, ptr) != 0) {
359 talloc_steal(new_parent, ptr);
365 add a name to an existing pointer - va_list version
367 static const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
369 static const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
371 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
372 tc->name = talloc_vasprintf(ptr, fmt, ap);
374 talloc_set_name_const(tc->name, ".name");
380 add a name to an existing pointer
382 const char *talloc_set_name(const void *ptr, const char *fmt, ...)
387 name = talloc_set_name_v(ptr, fmt, ap);
393 more efficient way to add a name to a pointer - the name must point to a
396 void talloc_set_name_const(const void *ptr, const char *name)
398 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
403 create a named talloc pointer. Any talloc pointer can be named, and
404 talloc_named() operates just like talloc() except that it allows you
407 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
413 ptr = _talloc(context, size);
414 if (ptr == NULL) return NULL;
417 name = talloc_set_name_v(ptr, fmt, ap);
429 create a named talloc pointer. Any talloc pointer can be named, and
430 talloc_named() operates just like talloc() except that it allows you
433 void *talloc_named_const(const void *context, size_t size, const char *name)
437 ptr = _talloc(context, size);
442 talloc_set_name_const(ptr, name);
448 return the name of a talloc ptr, or "UNNAMED"
450 const char *talloc_get_name(const void *ptr)
452 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
453 if (tc->name == TALLOC_MAGIC_REFERENCE) {
464 check if a pointer has the given name. If it does, return the pointer,
465 otherwise return NULL
467 void *talloc_check_name(const void *ptr, const char *name)
470 if (ptr == NULL) return NULL;
471 pname = talloc_get_name(ptr);
472 if (pname == name || strcmp(pname, name) == 0) {
473 return discard_const_p(void, ptr);
480 this is for compatibility with older versions of talloc
482 void *talloc_init(const char *fmt, ...)
488 ptr = _talloc(NULL, 0);
489 if (ptr == NULL) return NULL;
492 name = talloc_set_name_v(ptr, fmt, ap);
504 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
505 should probably not be used in new code. It's in here to keep the talloc
506 code consistent across Samba 3 and 4.
508 void talloc_free_children(void *ptr)
510 struct talloc_chunk *tc;
516 tc = talloc_chunk_from_ptr(ptr);
519 /* we need to work out who will own an abandoned child
520 if it cannot be freed. In priority order, the first
521 choice is owner of any remaining reference to this
522 pointer, the second choice is our parent, and the
523 final choice is the null context. */
524 void *child = TC_PTR_FROM_CHUNK(tc->child);
525 const void *new_parent = null_context;
526 if (tc->child->refs) {
527 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
528 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
530 if (talloc_free(child) == -1) {
531 if (new_parent == null_context) {
532 struct talloc_chunk *p = talloc_parent_chunk(ptr);
533 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
535 talloc_steal(new_parent, child);
541 free a talloc pointer. This also frees all child pointers of this
544 return 0 if the memory is actually freed, otherwise -1. The memory
545 will not be freed if the ref_count is > 1 or the destructor (if
546 any) returns non-zero
548 int talloc_free(void *ptr)
550 struct talloc_chunk *tc;
557 tc = talloc_chunk_from_ptr(ptr);
561 struct talloc_reference_handle *handle = tc->refs;
562 is_child = talloc_is_parent(handle, handle->ptr);
563 talloc_reference_destructor(tc->refs);
565 return talloc_free(ptr);
570 if (tc->flags & TALLOC_FLAG_LOOP) {
571 /* we have a free loop - stop looping */
575 if (tc->destructor) {
576 talloc_destructor_t d = tc->destructor;
577 if (d == (talloc_destructor_t)-1) {
580 tc->destructor = (talloc_destructor_t)-1;
585 tc->destructor = NULL;
589 _TLIST_REMOVE(tc->parent->child, tc);
590 if (tc->parent->child) {
591 tc->parent->child->parent = tc->parent;
594 if (tc->prev) tc->prev->next = tc->next;
595 if (tc->next) tc->next->prev = tc->prev;
598 tc->flags |= TALLOC_FLAG_LOOP;
599 talloc_free_children(ptr);
601 tc->flags |= TALLOC_FLAG_FREE;
611 A talloc version of realloc. The context argument is only used if
614 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
616 struct talloc_chunk *tc;
619 /* size zero is equivalent to free() */
625 if (size >= MAX_TALLOC_SIZE) {
629 /* realloc(NULL) is equavalent to malloc() */
631 return talloc_named_const(context, size, name);
634 tc = talloc_chunk_from_ptr(ptr);
636 /* don't allow realloc on referenced pointers */
641 /* by resetting magic we catch users of the old memory */
642 tc->flags |= TALLOC_FLAG_FREE;
645 new_ptr = malloc(size + TC_HDR_SIZE);
647 memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
651 new_ptr = realloc(tc, size + TC_HDR_SIZE);
654 tc->flags &= ~TALLOC_FLAG_FREE;
659 tc->flags &= ~TALLOC_FLAG_FREE;
661 tc->parent->child = new_ptr;
664 tc->child->parent = new_ptr;
675 talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
677 return TC_PTR_FROM_CHUNK(tc);
681 move a lump of memory from one talloc context to another return the
682 ptr on success, or NULL if it could not be transferred.
683 passing NULL as ptr will always return NULL with no side effects.
685 void *_talloc_steal(const void *new_ctx, const void *ptr)
687 struct talloc_chunk *tc, *new_tc;
693 if (new_ctx == NULL) {
694 new_ctx = null_context;
697 tc = talloc_chunk_from_ptr(ptr);
699 if (new_ctx == NULL) {
701 _TLIST_REMOVE(tc->parent->child, tc);
702 if (tc->parent->child) {
703 tc->parent->child->parent = tc->parent;
706 if (tc->prev) tc->prev->next = tc->next;
707 if (tc->next) tc->next->prev = tc->prev;
710 tc->parent = tc->next = tc->prev = NULL;
711 return discard_const_p(void, ptr);
714 new_tc = talloc_chunk_from_ptr(new_ctx);
716 if (tc == new_tc || tc->parent == new_tc) {
717 return discard_const_p(void, ptr);
721 _TLIST_REMOVE(tc->parent->child, tc);
722 if (tc->parent->child) {
723 tc->parent->child->parent = tc->parent;
726 if (tc->prev) tc->prev->next = tc->next;
727 if (tc->next) tc->next->prev = tc->prev;
731 if (new_tc->child) new_tc->child->parent = NULL;
732 _TLIST_ADD(new_tc->child, tc);
734 return discard_const_p(void, ptr);
738 return the total size of a talloc pool (subtree)
740 off_t talloc_total_size(const void *ptr)
743 struct talloc_chunk *c, *tc;
752 tc = talloc_chunk_from_ptr(ptr);
754 if (tc->flags & TALLOC_FLAG_LOOP) {
758 tc->flags |= TALLOC_FLAG_LOOP;
761 for (c=tc->child;c;c=c->next) {
762 total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
765 tc->flags &= ~TALLOC_FLAG_LOOP;
771 return the total number of blocks in a talloc pool (subtree)
773 off_t talloc_total_blocks(const void *ptr)
776 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
778 if (tc->flags & TALLOC_FLAG_LOOP) {
782 tc->flags |= TALLOC_FLAG_LOOP;
785 for (c=tc->child;c;c=c->next) {
786 total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
789 tc->flags &= ~TALLOC_FLAG_LOOP;
795 return the number of external references to a pointer
797 static int talloc_reference_count(const void *ptr)
799 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
800 struct talloc_reference_handle *h;
803 for (h=tc->refs;h;h=h->next) {
810 report on memory usage by all children of a pointer, giving a full tree view
812 void talloc_report_depth(const void *ptr, FILE *f, int depth)
814 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
816 if (tc->flags & TALLOC_FLAG_LOOP) {
820 tc->flags |= TALLOC_FLAG_LOOP;
822 for (c=tc->child;c;c=c->next) {
823 if (c->name == TALLOC_MAGIC_REFERENCE) {
824 struct talloc_reference_handle *handle = TC_PTR_FROM_CHUNK(c);
825 const char *name2 = talloc_get_name(handle->ptr);
826 fprintf(f, "%*sreference to: %s\n", depth*4, "", name2);
828 const char *name = talloc_get_name(TC_PTR_FROM_CHUNK(c));
829 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n",
832 (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c)),
833 (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)),
834 talloc_reference_count(TC_PTR_FROM_CHUNK(c)));
835 talloc_report_depth(TC_PTR_FROM_CHUNK(c), f, depth+1);
838 tc->flags &= ~TALLOC_FLAG_LOOP;
842 report on memory usage by all children of a pointer, giving a full tree view
844 void talloc_report_full(const void *ptr, FILE *f)
849 if (ptr == NULL) return;
851 fprintf(f,"full talloc report on '%s' (total %lu bytes in %lu blocks)\n",
852 talloc_get_name(ptr),
853 (unsigned long)talloc_total_size(ptr),
854 (unsigned long)talloc_total_blocks(ptr));
856 talloc_report_depth(ptr, f, 1);
861 report on memory usage by all children of a pointer
863 void talloc_report(const void *ptr, FILE *f)
865 struct talloc_chunk *c, *tc;
870 if (ptr == NULL) return;
872 fprintf(f,"talloc report on '%s' (total %lu bytes in %lu blocks)\n",
873 talloc_get_name(ptr),
874 (unsigned long)talloc_total_size(ptr),
875 (unsigned long)talloc_total_blocks(ptr));
877 tc = talloc_chunk_from_ptr(ptr);
879 for (c=tc->child;c;c=c->next) {
880 fprintf(f, "\t%-30s contains %6lu bytes in %3lu blocks\n",
881 talloc_get_name(TC_PTR_FROM_CHUNK(c)),
882 (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c)),
883 (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)));
889 report on any memory hanging off the null context
891 static void talloc_report_null(void)
893 if (talloc_total_size(null_context) != 0) {
894 talloc_report(null_context, stderr);
899 report on any memory hanging off the null context
901 static void talloc_report_null_full(void)
903 if (talloc_total_size(null_context) != 0) {
904 talloc_report_full(null_context, stderr);
909 enable tracking of the NULL context
911 void talloc_enable_null_tracking(void)
913 if (null_context == NULL) {
914 null_context = talloc_named_const(NULL, 0, "null_context");
919 enable leak reporting on exit
921 void talloc_enable_leak_report(void)
923 talloc_enable_null_tracking();
924 atexit(talloc_report_null);
928 enable full leak reporting on exit
930 void talloc_enable_leak_report_full(void)
932 talloc_enable_null_tracking();
933 atexit(talloc_report_null_full);
937 talloc and zero memory.
939 void *_talloc_zero(const void *ctx, size_t size, const char *name)
941 void *p = talloc_named_const(ctx, size, name);
944 memset(p, '\0', size);
952 memdup with a talloc.
954 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
956 void *newp = talloc_named_const(t, size, name);
959 memcpy(newp, p, size);
968 char *talloc_strdup(const void *t, const char *p)
974 ret = talloc_memdup(t, p, strlen(p) + 1);
976 talloc_set_name_const(ret, ret);
982 append to a talloced string
984 char *talloc_append_string(const void *t, char *orig, const char *append)
987 size_t olen = strlen(orig);
993 alenz = strlen(append) + 1;
995 ret = talloc_realloc(t, orig, char, olen + alenz);
999 /* append the string with the trailing \0 */
1000 memcpy(&ret[olen], append, alenz);
1006 strndup with a talloc
1008 char *talloc_strndup(const void *t, const char *p, size_t n)
1013 for (len=0; len<n && p[len]; len++) ;
1015 ret = _talloc(t, len + 1);
1016 if (!ret) { return NULL; }
1017 memcpy(ret, p, len);
1019 talloc_set_name_const(ret, ret);
1023 #ifndef HAVE_VA_COPY
1024 #ifdef HAVE___VA_COPY
1025 #define va_copy(dest, src) __va_copy(dest, src)
1027 #define va_copy(dest, src) (dest) = (src)
1031 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1040 /* this call looks strange, but it makes it work on older solaris boxes */
1041 if ((len = vsnprintf(&c, 1, fmt, ap2)) < 0) {
1045 ret = _talloc(t, len+1);
1048 vsnprintf(ret, len+1, fmt, ap2);
1049 talloc_set_name_const(ret, ret);
1057 Perform string formatting, and return a pointer to newly allocated
1058 memory holding the result, inside a memory pool.
1060 char *talloc_asprintf(const void *t, const char *fmt, ...)
1066 ret = talloc_vasprintf(t, fmt, ap);
1073 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1074 * and return @p s, which may have moved. Good for gradually
1075 * accumulating output into a string buffer.
1077 char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1079 struct talloc_chunk *tc;
1085 return talloc_vasprintf(NULL, fmt, ap);
1088 tc = talloc_chunk_from_ptr(s);
1092 s_len = tc->size - 1;
1093 if ((len = vsnprintf(&c, 1, fmt, ap2)) <= 0) {
1094 /* Either the vsnprintf failed or the format resulted in
1095 * no characters being formatted. In the former case, we
1096 * ought to return NULL, in the latter we ought to return
1097 * the original string. Most current callers of this
1098 * function expect it to never return NULL.
1103 s = talloc_realloc(NULL, s, char, s_len + len+1);
1104 if (!s) return NULL;
1108 vsnprintf(s+s_len, len+1, fmt, ap2);
1109 talloc_set_name_const(s, s);
1115 Realloc @p s to append the formatted result of @p fmt and return @p
1116 s, which may have moved. Good for gradually accumulating output
1117 into a string buffer.
1119 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1124 s = talloc_vasprintf_append(s, fmt, ap);
1130 alloc an array, checking for integer overflow in the array size
1132 void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1134 if (count >= MAX_TALLOC_SIZE/el_size) {
1137 return talloc_named_const(ctx, el_size * count, name);
1141 alloc an zero array, checking for integer overflow in the array size
1143 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1145 if (count >= MAX_TALLOC_SIZE/el_size) {
1148 return _talloc_zero(ctx, el_size * count, name);
1153 realloc an array, checking for integer overflow in the array size
1155 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1157 if (count >= MAX_TALLOC_SIZE/el_size) {
1160 return _talloc_realloc(ctx, ptr, el_size * count, name);
1164 a function version of talloc_realloc(), so it can be passed as a function pointer
1165 to libraries that want a realloc function (a realloc function encapsulates
1166 all the basic capabilities of an allocation library, which is why this is useful)
1168 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1170 return _talloc_realloc(context, ptr, size, NULL);
1174 static void talloc_autofree(void)
1176 talloc_free(cleanup_context);
1177 cleanup_context = NULL;
1181 return a context which will be auto-freed on exit
1182 this is useful for reducing the noise in leak reports
1184 void *talloc_autofree_context(void)
1186 if (cleanup_context == NULL) {
1187 cleanup_context = talloc_named_const(NULL, 0, "autofree_context");
1188 atexit(talloc_autofree);
1190 return cleanup_context;
1193 size_t talloc_get_size(const void *context)
1195 struct talloc_chunk *tc;
1197 if (context == NULL)
1200 tc = talloc_chunk_from_ptr(context);
1206 find a parent of this context that has the given name, if any
1208 void *talloc_find_parent_byname(const void *context, const char *name)
1210 struct talloc_chunk *tc;
1212 if (context == NULL) {
1216 tc = talloc_chunk_from_ptr(context);
1218 if (tc->name && strcmp(tc->name, name) == 0) {
1219 return TC_PTR_FROM_CHUNK(tc);
1221 while (tc && tc->prev) tc = tc->prev;
1230 show the parentage of a context
1232 void talloc_show_parents(const void *context, FILE *file)
1234 struct talloc_chunk *tc;
1236 if (context == NULL) {
1237 fprintf(file, "talloc no parents for NULL\n");
1241 tc = talloc_chunk_from_ptr(context);
1242 fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
1244 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
1245 while (tc && tc->prev) tc = tc->prev;
1253 return 1 if ptr is a parent of context
1255 int talloc_is_parent(const void *context, const char *ptr)
1257 struct talloc_chunk *tc;
1259 if (context == NULL) {
1263 tc = talloc_chunk_from_ptr(context);
1265 if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
1266 while (tc && tc->prev) tc = tc->prev;