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/
35 #if ((SAMBA_VERSION_MAJOR==3)&&(SAMBA_VERSION_MINOR<9))
36 /* This is to circumvent SAMBA3's paranoid malloc checker. Here in this file
37 * we trust ourselves... */
52 /* assume a modern system */
56 /* use this to force every realloc to change the pointer, to stress test
57 code that might not cope */
58 #define ALWAYS_REALLOC 0
61 #define MAX_TALLOC_SIZE 0x10000000
62 #define TALLOC_MAGIC 0xe814ec70
63 #define TALLOC_FLAG_FREE 0x01
64 #define TALLOC_FLAG_LOOP 0x02
65 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
67 /* by default we abort when given a bad pointer (such as when talloc_free() is called
68 on a pointer that came from malloc() */
70 #define TALLOC_ABORT(reason) abort()
73 #ifndef discard_const_p
74 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
75 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
77 # define discard_const_p(type, ptr) ((type *)(ptr))
81 /* this null_context is only used if talloc_enable_leak_report() or
82 talloc_enable_leak_report_full() is called, otherwise it remains
85 static const void *null_context;
86 static void *cleanup_context;
88 static void *talloc_steal(const void *new_ctx, const void *ptr);
90 struct talloc_reference_handle {
91 struct talloc_reference_handle *next, *prev;
95 typedef int (*talloc_destructor_t)(void *);
98 struct talloc_chunk *next, *prev;
99 struct talloc_chunk *parent, *child;
100 struct talloc_reference_handle *refs;
101 talloc_destructor_t destructor;
107 /* 16 byte alignment seems to keep everyone happy */
108 #define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
109 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
111 /* panic if we get a bad magic value */
112 static struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
114 const char *pp = ptr;
115 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
116 if ((tc->flags & ~0xF) != TALLOC_MAGIC) {
117 TALLOC_ABORT("Bad talloc magic value - unknown value");
119 if (tc->flags & TALLOC_FLAG_FREE) {
120 TALLOC_ABORT("Bad talloc magic value - double free");
125 /* hook into the front of the list */
126 #define _TLIST_ADD(list, p) \
130 (p)->next = (p)->prev = NULL; \
132 (list)->prev = (p); \
133 (p)->next = (list); \
139 /* remove an element from a list - element doesn't have to be in list. */
140 #define _TLIST_REMOVE(list, p) \
142 if ((p) == (list)) { \
143 (list) = (p)->next; \
144 if (list) (list)->prev = NULL; \
146 if ((p)->prev) (p)->prev->next = (p)->next; \
147 if ((p)->next) (p)->next->prev = (p)->prev; \
149 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
154 return the parent chunk of a pointer
156 static struct talloc_chunk *talloc_parent_chunk(const void *ptr)
158 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
159 while (tc->prev) tc=tc->prev;
163 void *talloc_parent(const void *ptr)
165 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
166 return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
170 Allocate a bit of memory as a child of an existing pointer
172 void *_talloc(const void *context, size_t size)
174 struct talloc_chunk *tc;
176 if (context == NULL) {
177 context = null_context;
180 if (size >= MAX_TALLOC_SIZE) {
184 tc = malloc(TC_HDR_SIZE+size);
185 if (tc == NULL) return NULL;
188 tc->flags = TALLOC_MAGIC;
189 tc->destructor = NULL;
195 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
200 parent->child->parent = NULL;
203 _TLIST_ADD(parent->child, tc);
205 tc->next = tc->prev = tc->parent = NULL;
208 return TC_PTR_FROM_CHUNK(tc);
213 setup a destructor to be called on free of a pointer
214 the destructor should return 0 on success, or -1 on failure.
215 if the destructor fails then the free is failed, and the memory can
216 be continued to be used
218 void talloc_set_destructor(const void *ptr, int (*destructor)(void *))
220 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
221 tc->destructor = destructor;
225 increase the reference count on a piece of memory.
227 void talloc_increase_ref_count(const void *ptr)
229 talloc_reference(null_context, ptr);
233 helper for talloc_reference()
235 static int talloc_reference_destructor(void *ptr)
237 struct talloc_reference_handle *handle = ptr;
238 struct talloc_chunk *tc1 = talloc_chunk_from_ptr(ptr);
239 struct talloc_chunk *tc2 = talloc_chunk_from_ptr(handle->ptr);
240 if (tc1->destructor != (talloc_destructor_t)-1) {
241 tc1->destructor = NULL;
243 _TLIST_REMOVE(tc2->refs, handle);
249 make a secondary reference to a pointer, hanging off the given context.
250 the pointer remains valid until both the original caller and this given
253 the major use for this is when two different structures need to reference the
254 same underlying data, and you want to be able to free the two instances separately,
257 void *talloc_reference(const void *context, const void *ptr)
259 struct talloc_chunk *tc;
260 struct talloc_reference_handle *handle;
261 if (ptr == NULL) return NULL;
263 tc = talloc_chunk_from_ptr(ptr);
264 handle = talloc_named_const(context, sizeof(*handle), TALLOC_MAGIC_REFERENCE);
266 if (handle == NULL) return NULL;
268 /* note that we hang the destructor off the handle, not the
269 main context as that allows the caller to still setup their
270 own destructor on the context if they want to */
271 talloc_set_destructor(handle, talloc_reference_destructor);
272 handle->ptr = discard_const_p(void, ptr);
273 _TLIST_ADD(tc->refs, handle);
278 remove a secondary reference to a pointer. This undo's what
279 talloc_reference() has done. The context and pointer arguments
280 must match those given to a talloc_reference()
282 static int talloc_unreference(const void *context, const void *ptr)
284 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
285 struct talloc_reference_handle *h;
287 if (context == NULL) {
288 context = null_context;
291 for (h=tc->refs;h;h=h->next) {
292 struct talloc_chunk *p = talloc_parent_chunk(h);
294 if (context == NULL) break;
295 } else if (TC_PTR_FROM_CHUNK(p) == context) {
303 talloc_set_destructor(h, NULL);
304 _TLIST_REMOVE(tc->refs, h);
310 remove a specific parent context from a pointer. This is a more
311 controlled varient of talloc_free()
313 int talloc_unlink(const void *context, void *ptr)
315 struct talloc_chunk *tc_p, *new_p;
322 if (context == NULL) {
323 context = null_context;
326 if (talloc_unreference(context, ptr) == 0) {
330 if (context == NULL) {
331 if (talloc_parent_chunk(ptr) != NULL) {
335 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
340 tc_p = talloc_chunk_from_ptr(ptr);
342 if (tc_p->refs == NULL) {
343 return talloc_free(ptr);
346 new_p = talloc_parent_chunk(tc_p->refs);
348 new_parent = TC_PTR_FROM_CHUNK(new_p);
353 if (talloc_unreference(new_parent, ptr) != 0) {
357 talloc_steal(new_parent, ptr);
363 add a name to an existing pointer - va_list version
365 static void talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
367 static void talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
369 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
370 tc->name = talloc_vasprintf(ptr, fmt, ap);
372 talloc_set_name_const(tc->name, ".name");
377 add a name to an existing pointer
379 void talloc_set_name(const void *ptr, const char *fmt, ...)
383 talloc_set_name_v(ptr, fmt, ap);
388 more efficient way to add a name to a pointer - the name must point to a
391 void talloc_set_name_const(const void *ptr, const char *name)
393 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
398 create a named talloc pointer. Any talloc pointer can be named, and
399 talloc_named() operates just like talloc() except that it allows you
402 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
407 ptr = _talloc(context, size);
408 if (ptr == NULL) return NULL;
411 talloc_set_name_v(ptr, fmt, ap);
418 create a named talloc pointer. Any talloc pointer can be named, and
419 talloc_named() operates just like talloc() except that it allows you
422 void *talloc_named_const(const void *context, size_t size, const char *name)
426 ptr = _talloc(context, size);
431 talloc_set_name_const(ptr, name);
437 return the name of a talloc ptr, or "UNNAMED"
439 const char *talloc_get_name(const void *ptr)
441 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
442 if (tc->name == TALLOC_MAGIC_REFERENCE) {
453 check if a pointer has the given name. If it does, return the pointer,
454 otherwise return NULL
456 void *talloc_check_name(const void *ptr, const char *name)
459 if (ptr == NULL) return NULL;
460 pname = talloc_get_name(ptr);
461 if (pname == name || strcmp(pname, name) == 0) {
462 return discard_const_p(void, ptr);
469 this is for compatibility with older versions of talloc
471 void *talloc_init(const char *fmt, ...)
476 talloc_enable_null_tracking();
478 ptr = _talloc(NULL, 0);
479 if (ptr == NULL) return NULL;
482 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;
541 tc = talloc_chunk_from_ptr(ptr);
545 struct talloc_reference_handle *handle = tc->refs;
546 is_child = talloc_is_parent(handle, handle->ptr);
547 talloc_reference_destructor(tc->refs);
549 return talloc_free(ptr);
554 if (tc->flags & TALLOC_FLAG_LOOP) {
555 /* we have a free loop - stop looping */
559 if (tc->destructor) {
560 talloc_destructor_t d = tc->destructor;
561 if (d == (talloc_destructor_t)-1) {
564 tc->destructor = (talloc_destructor_t)-1;
569 tc->destructor = NULL;
572 tc->flags |= TALLOC_FLAG_LOOP;
574 talloc_free_children(ptr);
577 _TLIST_REMOVE(tc->parent->child, tc);
578 if (tc->parent->child) {
579 tc->parent->child->parent = tc->parent;
582 if (tc->prev) tc->prev->next = tc->next;
583 if (tc->next) tc->next->prev = tc->prev;
586 tc->flags |= TALLOC_FLAG_FREE;
595 A talloc version of realloc. The context argument is only used if
598 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
600 struct talloc_chunk *tc;
603 /* size zero is equivalent to free() */
609 if (size >= MAX_TALLOC_SIZE) {
613 /* realloc(NULL) is equavalent to malloc() */
615 return talloc_named_const(context, size, name);
618 tc = talloc_chunk_from_ptr(ptr);
620 /* don't allow realloc on referenced pointers */
625 /* by resetting magic we catch users of the old memory */
626 tc->flags |= TALLOC_FLAG_FREE;
629 new_ptr = malloc(size + TC_HDR_SIZE);
631 memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
635 new_ptr = realloc(tc, size + TC_HDR_SIZE);
638 tc->flags &= ~TALLOC_FLAG_FREE;
643 tc->flags &= ~TALLOC_FLAG_FREE;
645 tc->parent->child = new_ptr;
648 tc->child->parent = new_ptr;
659 talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
661 return TC_PTR_FROM_CHUNK(tc);
665 move a lump of memory from one talloc context to another return the
666 ptr on success, or NULL if it could not be transferred.
667 passing NULL as ptr will always return NULL with no side effects.
669 static void *talloc_steal(const void *new_ctx, const void *ptr)
671 struct talloc_chunk *tc, *new_tc;
677 if (new_ctx == NULL) {
678 new_ctx = null_context;
681 tc = talloc_chunk_from_ptr(ptr);
683 if (new_ctx == NULL) {
685 _TLIST_REMOVE(tc->parent->child, tc);
686 if (tc->parent->child) {
687 tc->parent->child->parent = tc->parent;
690 if (tc->prev) tc->prev->next = tc->next;
691 if (tc->next) tc->next->prev = tc->prev;
694 tc->parent = tc->next = tc->prev = NULL;
695 return discard_const_p(void, ptr);
698 new_tc = talloc_chunk_from_ptr(new_ctx);
700 if (tc == new_tc || tc->parent == new_tc) {
701 return discard_const_p(void, ptr);
705 _TLIST_REMOVE(tc->parent->child, tc);
706 if (tc->parent->child) {
707 tc->parent->child->parent = tc->parent;
710 if (tc->prev) tc->prev->next = tc->next;
711 if (tc->next) tc->next->prev = tc->prev;
715 if (new_tc->child) new_tc->child->parent = NULL;
716 _TLIST_ADD(new_tc->child, tc);
718 return discard_const_p(void, ptr);
722 return the total size of a talloc pool (subtree)
724 off_t talloc_total_size(const void *ptr)
727 struct talloc_chunk *c, *tc;
736 tc = talloc_chunk_from_ptr(ptr);
738 if (tc->flags & TALLOC_FLAG_LOOP) {
742 tc->flags |= TALLOC_FLAG_LOOP;
745 for (c=tc->child;c;c=c->next) {
746 total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
749 tc->flags &= ~TALLOC_FLAG_LOOP;
755 return the total number of blocks in a talloc pool (subtree)
757 off_t talloc_total_blocks(const void *ptr)
760 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
762 if (tc->flags & TALLOC_FLAG_LOOP) {
766 tc->flags |= TALLOC_FLAG_LOOP;
769 for (c=tc->child;c;c=c->next) {
770 total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
773 tc->flags &= ~TALLOC_FLAG_LOOP;
779 return the number of external references to a pointer
781 static int talloc_reference_count(const void *ptr)
783 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
784 struct talloc_reference_handle *h;
787 for (h=tc->refs;h;h=h->next) {
794 report on memory usage by all children of a pointer, giving a full tree view
796 void talloc_report_depth(const void *ptr, FILE *f, int depth)
798 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
800 if (tc->flags & TALLOC_FLAG_LOOP) {
804 tc->flags |= TALLOC_FLAG_LOOP;
806 for (c=tc->child;c;c=c->next) {
807 if (c->name == TALLOC_MAGIC_REFERENCE) {
808 struct talloc_reference_handle *handle = TC_PTR_FROM_CHUNK(c);
809 const char *name2 = talloc_get_name(handle->ptr);
810 fprintf(f, "%*sreference to: %s\n", depth*4, "", name2);
812 const char *name = talloc_get_name(TC_PTR_FROM_CHUNK(c));
813 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n",
816 (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c)),
817 (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)),
818 talloc_reference_count(TC_PTR_FROM_CHUNK(c)));
819 talloc_report_depth(TC_PTR_FROM_CHUNK(c), f, depth+1);
822 tc->flags &= ~TALLOC_FLAG_LOOP;
826 report on memory usage by all children of a pointer, giving a full tree view
828 void talloc_report_full(const void *ptr, FILE *f)
833 if (ptr == NULL) return;
835 fprintf(f,"full talloc report on '%s' (total %lu bytes in %lu blocks)\n",
836 talloc_get_name(ptr),
837 (unsigned long)talloc_total_size(ptr),
838 (unsigned long)talloc_total_blocks(ptr));
840 talloc_report_depth(ptr, f, 1);
845 report on memory usage by all children of a pointer
847 void talloc_report(const void *ptr, FILE *f)
849 struct talloc_chunk *c, *tc;
854 if (ptr == NULL) return;
856 fprintf(f,"talloc report on '%s' (total %lu bytes in %lu blocks)\n",
857 talloc_get_name(ptr),
858 (unsigned long)talloc_total_size(ptr),
859 (unsigned long)talloc_total_blocks(ptr));
861 tc = talloc_chunk_from_ptr(ptr);
863 for (c=tc->child;c;c=c->next) {
864 fprintf(f, "\t%-30s contains %6lu bytes in %3lu blocks\n",
865 talloc_get_name(TC_PTR_FROM_CHUNK(c)),
866 (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c)),
867 (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)));
873 report on any memory hanging off the null context
875 static void talloc_report_null(void)
877 if (talloc_total_size(null_context) != 0) {
878 talloc_report(null_context, stderr);
883 report on any memory hanging off the null context
885 static void talloc_report_null_full(void)
887 if (talloc_total_size(null_context) != 0) {
888 talloc_report_full(null_context, stderr);
893 free allocated global memory
896 void talloc_nc_free(void)
899 talloc_free( (void*)null_context );
903 enable tracking of the NULL context
905 void talloc_enable_null_tracking(void)
907 if (null_context == NULL) {
908 null_context = talloc_named_const(NULL, 0, "null_context");
913 /* Ugly calls to Samba-specific sprintf_append... JRA. */
916 report on memory usage by all children of a pointer, giving a full tree view
918 static void talloc_report_depth_str(const void *ptr, char **pps, ssize_t *plen, size_t *pbuflen, int depth)
920 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
922 if (tc->flags & TALLOC_FLAG_LOOP) {
926 tc->flags |= TALLOC_FLAG_LOOP;
928 for (c=tc->child;c;c=c->next) {
929 if (c->name == TALLOC_MAGIC_REFERENCE) {
930 struct talloc_reference_handle *handle = TC_PTR_FROM_CHUNK(c);
931 const char *name2 = talloc_get_name(handle->ptr);
933 sprintf_append(NULL, pps, plen, pbuflen,
934 "%*sreference to: %s\n", depth*4, "", name2);
937 const char *name = talloc_get_name(TC_PTR_FROM_CHUNK(c));
939 sprintf_append(NULL, pps, plen, pbuflen,
940 "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n",
943 (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c)),
944 (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c)),
945 talloc_reference_count(TC_PTR_FROM_CHUNK(c)));
947 talloc_report_depth_str(TC_PTR_FROM_CHUNK(c), pps, plen, pbuflen, depth+1);
950 tc->flags &= ~TALLOC_FLAG_LOOP;
954 report on memory usage by all children of a pointer
956 char *talloc_describe_all(void)
962 if (null_context == NULL) {
966 sprintf_append(NULL, &s, &len, &buflen,
967 "full talloc report on '%s' (total %lu bytes in %lu blocks)\n",
968 talloc_get_name(null_context),
969 (unsigned long)talloc_total_size(null_context),
970 (unsigned long)talloc_total_blocks(null_context));
975 talloc_report_depth_str(null_context, &s, &len, &buflen, 1);
981 enable leak reporting on exit
983 void talloc_enable_leak_report(void)
985 talloc_enable_null_tracking();
986 atexit(talloc_report_null);
990 enable full leak reporting on exit
992 void talloc_enable_leak_report_full(void)
994 talloc_enable_null_tracking();
995 atexit(talloc_report_null_full);
999 talloc and zero memory.
1001 void *_talloc_zero(const void *ctx, size_t size, const char *name)
1003 void *p = talloc_named_const(ctx, size, name);
1006 memset(p, '\0', size);
1014 memdup with a talloc.
1016 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
1018 void *newp = talloc_named_const(t, size, name);
1021 memcpy(newp, p, size);
1028 strdup with a talloc
1030 char *talloc_strdup(const void *t, const char *p)
1036 ret = talloc_memdup(t, p, strlen(p) + 1);
1038 talloc_set_name_const(ret, ret);
1044 append to a talloced string
1046 char *talloc_append_string(const void *t, char *orig, const char *append)
1049 size_t olen = strlen(orig);
1055 alenz = strlen(append) + 1;
1057 ret = talloc_realloc(t, orig, char, olen + alenz);
1061 /* append the string with the trailing \0 */
1062 memcpy(&ret[olen], append, alenz);
1068 strndup with a talloc
1070 char *talloc_strndup(const void *t, const char *p, size_t n)
1075 for (len=0; len<n && p[len]; len++) ;
1077 ret = _talloc(t, len + 1);
1078 if (!ret) { return NULL; }
1079 memcpy(ret, p, len);
1081 talloc_set_name_const(ret, ret);
1087 #define VA_COPY(dest, src) va_copy(dest, src)
1088 #elif defined(HAVE___VA_COPY)
1089 #define VA_COPY(dest, src) __va_copy(dest, src)
1091 #define VA_COPY(dest, src) (dest) = (src)
1095 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1104 /* this call looks strange, but it makes it work on older solaris boxes */
1105 if ((len = vsnprintf(&c, 1, fmt, ap2)) < 0) {
1109 ret = _talloc(t, len+1);
1112 vsnprintf(ret, len+1, fmt, ap2);
1113 talloc_set_name_const(ret, ret);
1121 Perform string formatting, and return a pointer to newly allocated
1122 memory holding the result, inside a memory pool.
1124 char *talloc_asprintf(const void *t, const char *fmt, ...)
1130 ret = talloc_vasprintf(t, fmt, ap);
1137 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1138 * and return @p s, which may have moved. Good for gradually
1139 * accumulating output into a string buffer.
1142 char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1144 struct talloc_chunk *tc;
1149 return talloc_vasprintf(NULL, fmt, ap);
1152 tc = talloc_chunk_from_ptr(s);
1156 s_len = tc->size - 1;
1157 if ((len = vsnprintf(NULL, 0, fmt, ap2)) <= 0) {
1158 /* Either the vsnprintf failed or the format resulted in
1159 * no characters being formatted. In the former case, we
1160 * ought to return NULL, in the latter we ought to return
1161 * the original string. Most current callers of this
1162 * function expect it to never return NULL.
1167 s = talloc_realloc(NULL, s, char, s_len + len+1);
1168 if (!s) return NULL;
1172 vsnprintf(s+s_len, len+1, fmt, ap2);
1173 talloc_set_name_const(s, s);
1179 Realloc @p s to append the formatted result of @p fmt and return @p
1180 s, which may have moved. Good for gradually accumulating output
1181 into a string buffer.
1183 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1188 s = talloc_vasprintf_append(s, fmt, ap);
1194 alloc an array, checking for integer overflow in the array size
1196 void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1198 if (count >= MAX_TALLOC_SIZE/el_size) {
1201 return talloc_named_const(ctx, el_size * count, name);
1205 alloc an zero array, checking for integer overflow in the array size
1207 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1209 if (count >= MAX_TALLOC_SIZE/el_size) {
1212 return _talloc_zero(ctx, el_size * count, name);
1217 realloc an array, checking for integer overflow in the array size
1219 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1221 if (count >= MAX_TALLOC_SIZE/el_size) {
1224 return _talloc_realloc(ctx, ptr, el_size * count, name);
1228 a function version of talloc_realloc(), so it can be passed as a function pointer
1229 to libraries that want a realloc function (a realloc function encapsulates
1230 all the basic capabilities of an allocation library, which is why this is useful)
1232 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1234 return _talloc_realloc(context, ptr, size, NULL);
1238 static void talloc_autofree(void)
1240 talloc_free(cleanup_context);
1241 cleanup_context = NULL;
1245 return a context which will be auto-freed on exit
1246 this is useful for reducing the noise in leak reports
1248 void *talloc_autofree_context(void)
1250 if (cleanup_context == NULL) {
1251 cleanup_context = talloc_named_const(NULL, 0, "autofree_context");
1252 atexit(talloc_autofree);
1254 return cleanup_context;
1257 size_t talloc_get_size(const void *context)
1259 struct talloc_chunk *tc;
1261 if (context == NULL)
1264 tc = talloc_chunk_from_ptr(context);
1270 find a parent of this context that has the given name, if any
1272 void *talloc_find_parent_byname(const void *context, const char *name)
1274 struct talloc_chunk *tc;
1276 if (context == NULL) {
1280 tc = talloc_chunk_from_ptr(context);
1282 if (tc->name && strcmp(tc->name, name) == 0) {
1283 return TC_PTR_FROM_CHUNK(tc);
1285 while (tc && tc->prev) tc = tc->prev;
1295 show the parentage of a context
1297 void talloc_show_parents(const void *context, FILE *file)
1299 struct talloc_chunk *tc;
1301 if (context == NULL) {
1302 fprintf(file, "talloc no parents for NULL\n");
1306 tc = talloc_chunk_from_ptr(context);
1307 fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
1309 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
1310 while (tc && tc->prev) tc = tc->prev;
1318 return 1 if ptr is a parent of context
1320 int talloc_is_parent(const void *context, const char *ptr)
1322 struct talloc_chunk *tc;
1324 if (context == NULL) {
1328 tc = talloc_chunk_from_ptr(context);
1330 if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
1331 while (tc && tc->prev) tc = tc->prev;