r6743: Merge r6741 from 4_0
[Samba/nascimento.git] / source3 / lib / talloc.c
blob46abd89bac5e49c64ee05dc49abb8c8d8c59e294
1 /*
2 Samba Unix SMB/CIFS implementation.
4 Samba trivial allocation library - new interface
6 NOTE: Please read talloc_guide.txt for full documentation
8 Copyright (C) Andrew Tridgell 2004
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 inspired by http://swapped.cc/halloc/
30 #ifdef _SAMBA_BUILD_
31 #include "includes.h"
32 #if ((SAMBA_VERSION_MAJOR==3)&&(SAMBA_VERSION_MINOR<9))
33 /* This is to circumvent SAMBA3's paranoid malloc checker. Here in this file
34 * we trust ourselves... */
35 #ifdef malloc
36 #undef malloc
37 #endif
38 #ifdef realloc
39 #undef realloc
40 #endif
41 #endif
42 #else
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <stdarg.h>
47 #include <stdint.h>
48 #include "talloc.h"
49 /* assume a modern system */
50 #define HAVE_VA_COPY
51 #endif
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 0xe814ec4f
60 #define TALLOC_MAGIC_FREE 0x7faebef3
61 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
63 /* by default we abort when given a bad pointer (such as when talloc_free() is called
64 on a pointer that came from malloc() */
65 #ifndef TALLOC_ABORT
66 #define TALLOC_ABORT(reason) abort()
67 #endif
69 #ifndef discard_const_p
70 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
71 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
72 #else
73 # define discard_const_p(type, ptr) ((type *)(ptr))
74 #endif
75 #endif
77 /* this null_context is only used if talloc_enable_leak_report() or
78 talloc_enable_leak_report_full() is called, otherwise it remains
79 NULL
81 static const void *null_context;
82 static void *cleanup_context;
85 struct talloc_reference_handle {
86 struct talloc_reference_handle *next, *prev;
87 void *ptr;
90 typedef int (*talloc_destructor_t)(void *);
92 struct talloc_chunk {
93 struct talloc_chunk *next, *prev;
94 struct talloc_chunk *parent, *child;
95 struct talloc_reference_handle *refs;
96 size_t size;
97 unsigned magic;
98 talloc_destructor_t destructor;
99 const char *name;
102 /* panic if we get a bad magic value */
103 static struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
105 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, ptr)-1;
106 if (tc->magic != TALLOC_MAGIC) {
107 if (tc->magic == TALLOC_MAGIC_FREE) {
108 TALLOC_ABORT("Bad talloc magic value - double free");
109 } else {
110 TALLOC_ABORT("Bad talloc magic value - unknown value");
114 return tc;
117 /* hook into the front of the list */
118 #define _TLIST_ADD(list, p) \
119 do { \
120 if (!(list)) { \
121 (list) = (p); \
122 (p)->next = (p)->prev = NULL; \
123 } else { \
124 (list)->prev = (p); \
125 (p)->next = (list); \
126 (p)->prev = NULL; \
127 (list) = (p); \
129 } while (0)
131 /* remove an element from a list - element doesn't have to be in list. */
132 #define _TLIST_REMOVE(list, p) \
133 do { \
134 if ((p) == (list)) { \
135 (list) = (p)->next; \
136 if (list) (list)->prev = NULL; \
137 } else { \
138 if ((p)->prev) (p)->prev->next = (p)->next; \
139 if ((p)->next) (p)->next->prev = (p)->prev; \
141 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
142 } while (0)
146 return the parent chunk of a pointer
148 static struct talloc_chunk *talloc_parent_chunk(const void *ptr)
150 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
151 while (tc->prev) tc=tc->prev;
152 return tc->parent;
155 void *talloc_parent(const void *ptr)
157 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
158 return (void *)(tc+1);
162 Allocate a bit of memory as a child of an existing pointer
164 void *_talloc(const void *context, size_t size)
166 struct talloc_chunk *tc;
168 if (context == NULL) {
169 context = null_context;
172 if (size >= MAX_TALLOC_SIZE) {
173 return NULL;
176 tc = malloc(sizeof(*tc)+size);
177 if (tc == NULL) return NULL;
179 tc->size = size;
180 tc->magic = TALLOC_MAGIC;
181 tc->destructor = NULL;
182 tc->child = NULL;
183 tc->name = NULL;
184 tc->refs = NULL;
186 if (context) {
187 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
189 tc->parent = parent;
191 if (parent->child) {
192 parent->child->parent = NULL;
195 _TLIST_ADD(parent->child, tc);
196 } else {
197 tc->next = tc->prev = tc->parent = NULL;
200 return (void *)(tc+1);
205 setup a destructor to be called on free of a pointer
206 the destructor should return 0 on success, or -1 on failure.
207 if the destructor fails then the free is failed, and the memory can
208 be continued to be used
210 void talloc_set_destructor(const void *ptr, int (*destructor)(void *))
212 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
213 tc->destructor = destructor;
217 increase the reference count on a piece of memory.
219 void talloc_increase_ref_count(const void *ptr)
221 talloc_reference(null_context, ptr);
225 helper for talloc_reference()
227 static int talloc_reference_destructor(void *ptr)
229 struct talloc_reference_handle *handle = ptr;
230 struct talloc_chunk *tc1 = talloc_chunk_from_ptr(ptr);
231 struct talloc_chunk *tc2 = talloc_chunk_from_ptr(handle->ptr);
232 if (tc1->destructor != (talloc_destructor_t)-1) {
233 tc1->destructor = NULL;
235 _TLIST_REMOVE(tc2->refs, handle);
236 talloc_free(handle);
237 return 0;
241 make a secondary reference to a pointer, hanging off the given context.
242 the pointer remains valid until both the original caller and this given
243 context are freed.
245 the major use for this is when two different structures need to reference the
246 same underlying data, and you want to be able to free the two instances separately,
247 and in either order
249 void *talloc_reference(const void *context, const void *ptr)
251 struct talloc_chunk *tc;
252 struct talloc_reference_handle *handle;
253 if (ptr == NULL) return NULL;
255 tc = talloc_chunk_from_ptr(ptr);
256 handle = talloc_named_const(context, sizeof(*handle), TALLOC_MAGIC_REFERENCE);
258 if (handle == NULL) return NULL;
260 /* note that we hang the destructor off the handle, not the
261 main context as that allows the caller to still setup their
262 own destructor on the context if they want to */
263 talloc_set_destructor(handle, talloc_reference_destructor);
264 handle->ptr = discard_const_p(void, ptr);
265 _TLIST_ADD(tc->refs, handle);
266 return handle->ptr;
270 remove a secondary reference to a pointer. This undo's what
271 talloc_reference() has done. The context and pointer arguments
272 must match those given to a talloc_reference()
274 static int talloc_unreference(const void *context, const void *ptr)
276 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
277 struct talloc_reference_handle *h;
279 if (context == NULL) {
280 context = null_context;
283 for (h=tc->refs;h;h=h->next) {
284 struct talloc_chunk *p = talloc_parent_chunk(h);
285 if ((p==NULL && context==NULL) || p+1 == context) break;
287 if (h == NULL) {
288 return -1;
291 talloc_set_destructor(h, NULL);
292 _TLIST_REMOVE(tc->refs, h);
293 talloc_free(h);
294 return 0;
298 remove a specific parent context from a pointer. This is a more
299 controlled varient of talloc_free()
301 int talloc_unlink(const void *context, void *ptr)
303 struct talloc_chunk *tc_p, *new_p;
304 void *new_parent;
306 if (ptr == NULL) {
307 return -1;
310 if (context == NULL) {
311 context = null_context;
314 if (talloc_unreference(context, ptr) == 0) {
315 return 0;
318 if (context == NULL) {
319 if (talloc_parent_chunk(ptr) != NULL) {
320 return -1;
322 } else {
323 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
324 return -1;
328 tc_p = talloc_chunk_from_ptr(ptr);
330 if (tc_p->refs == NULL) {
331 return talloc_free(ptr);
334 new_p = talloc_parent_chunk(tc_p->refs);
335 if (new_p) {
336 new_parent = new_p+1;
337 } else {
338 new_parent = NULL;
341 if (talloc_unreference(new_parent, ptr) != 0) {
342 return -1;
345 talloc_steal(new_parent, ptr);
347 return 0;
351 add a name to an existing pointer - va_list version
353 static void talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
355 static void talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
357 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
358 tc->name = talloc_vasprintf(ptr, fmt, ap);
359 if (tc->name) {
360 talloc_set_name_const(tc->name, ".name");
365 add a name to an existing pointer
367 void talloc_set_name(const void *ptr, const char *fmt, ...)
369 va_list ap;
370 va_start(ap, fmt);
371 talloc_set_name_v(ptr, fmt, ap);
372 va_end(ap);
376 more efficient way to add a name to a pointer - the name must point to a
377 true string constant
379 void talloc_set_name_const(const void *ptr, const char *name)
381 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
382 tc->name = name;
386 create a named talloc pointer. Any talloc pointer can be named, and
387 talloc_named() operates just like talloc() except that it allows you
388 to name the pointer.
390 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
392 va_list ap;
393 void *ptr;
395 ptr = _talloc(context, size);
396 if (ptr == NULL) return NULL;
398 va_start(ap, fmt);
399 talloc_set_name_v(ptr, fmt, ap);
400 va_end(ap);
402 return ptr;
406 create a named talloc pointer. Any talloc pointer can be named, and
407 talloc_named() operates just like talloc() except that it allows you
408 to name the pointer.
410 void *talloc_named_const(const void *context, size_t size, const char *name)
412 void *ptr;
414 ptr = _talloc(context, size);
415 if (ptr == NULL) {
416 return NULL;
419 talloc_set_name_const(ptr, name);
421 return ptr;
425 return the name of a talloc ptr, or "UNNAMED"
427 const char *talloc_get_name(const void *ptr)
429 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
430 if (tc->name == TALLOC_MAGIC_REFERENCE) {
431 return ".reference";
433 if (tc->name) {
434 return tc->name;
436 return "UNNAMED";
441 check if a pointer has the given name. If it does, return the pointer,
442 otherwise return NULL
444 void *talloc_check_name(const void *ptr, const char *name)
446 const char *pname;
447 if (ptr == NULL) return NULL;
448 pname = talloc_get_name(ptr);
449 if (pname == name || strcmp(pname, name) == 0) {
450 return discard_const_p(void, ptr);
452 return NULL;
457 this is for compatibility with older versions of talloc
459 void *talloc_init(const char *fmt, ...)
461 va_list ap;
462 void *ptr;
464 ptr = _talloc(NULL, 0);
465 if (ptr == NULL) return NULL;
467 va_start(ap, fmt);
468 talloc_set_name_v(ptr, fmt, ap);
469 va_end(ap);
471 return ptr;
475 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
476 should probably not be used in new code. It's in here to keep the talloc
477 code consistent across Samba 3 and 4.
479 void talloc_free_children(void *ptr)
481 struct talloc_chunk *tc;
483 if (ptr == NULL) {
484 return;
487 tc = talloc_chunk_from_ptr(ptr);
489 while (tc->child) {
490 /* we need to work out who will own an abandoned child
491 if it cannot be freed. In priority order, the first
492 choice is owner of any remaining reference to this
493 pointer, the second choice is our parent, and the
494 final choice is the null context. */
495 void *child = tc->child+1;
496 const void *new_parent = null_context;
497 if (tc->child->refs) {
498 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
499 if (p) new_parent = p+1;
501 if (talloc_free(child) == -1) {
502 if (new_parent == null_context) {
503 struct talloc_chunk *p = talloc_parent_chunk(ptr);
504 if (p) new_parent = p+1;
506 talloc_steal(new_parent, child);
512 free a talloc pointer. This also frees all child pointers of this
513 pointer recursively
515 return 0 if the memory is actually freed, otherwise -1. The memory
516 will not be freed if the ref_count is > 1 or the destructor (if
517 any) returns non-zero
519 int talloc_free(void *ptr)
521 struct talloc_chunk *tc;
523 if (ptr == NULL) {
524 return -1;
527 tc = talloc_chunk_from_ptr(ptr);
529 if (tc->refs) {
530 talloc_reference_destructor(tc->refs);
531 return -1;
534 if (tc->destructor) {
535 talloc_destructor_t d = tc->destructor;
536 if (d == (talloc_destructor_t)-1) {
537 return -1;
539 tc->destructor = (talloc_destructor_t)-1;
540 if (d(ptr) == -1) {
541 tc->destructor = d;
542 return -1;
544 tc->destructor = NULL;
547 talloc_free_children(ptr);
549 if (tc->parent) {
550 _TLIST_REMOVE(tc->parent->child, tc);
551 if (tc->parent->child) {
552 tc->parent->child->parent = tc->parent;
554 } else {
555 if (tc->prev) tc->prev->next = tc->next;
556 if (tc->next) tc->next->prev = tc->prev;
559 tc->magic = TALLOC_MAGIC_FREE;
561 free(tc);
562 return 0;
568 A talloc version of realloc. The context argument is only used if
569 ptr is NULL
571 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
573 struct talloc_chunk *tc;
574 void *new_ptr;
576 /* size zero is equivalent to free() */
577 if (size == 0) {
578 talloc_free(ptr);
579 return NULL;
582 if (size >= MAX_TALLOC_SIZE) {
583 return NULL;
586 /* realloc(NULL) is equavalent to malloc() */
587 if (ptr == NULL) {
588 return talloc_named_const(context, size, name);
591 tc = talloc_chunk_from_ptr(ptr);
593 /* don't allow realloc on referenced pointers */
594 if (tc->refs) {
595 return NULL;
598 /* by resetting magic we catch users of the old memory */
599 tc->magic = TALLOC_MAGIC_FREE;
601 #if ALWAYS_REALLOC
602 new_ptr = malloc(size + sizeof(*tc));
603 if (new_ptr) {
604 memcpy(new_ptr, tc, tc->size + sizeof(*tc));
605 free(tc);
607 #else
608 new_ptr = realloc(tc, size + sizeof(*tc));
609 #endif
610 if (!new_ptr) {
611 tc->magic = TALLOC_MAGIC;
612 return NULL;
615 tc = new_ptr;
616 tc->magic = TALLOC_MAGIC;
617 if (tc->parent) {
618 tc->parent->child = new_ptr;
620 if (tc->child) {
621 tc->child->parent = new_ptr;
624 if (tc->prev) {
625 tc->prev->next = tc;
627 if (tc->next) {
628 tc->next->prev = tc;
631 tc->size = size;
632 talloc_set_name_const(tc+1, name);
634 return (void *)(tc+1);
638 move a lump of memory from one talloc context to another return the
639 ptr on success, or NULL if it could not be transferred.
640 passing NULL as ptr will always return NULL with no side effects.
642 void *talloc_steal(const void *new_ctx, const void *ptr)
644 struct talloc_chunk *tc, *new_tc;
646 if (!ptr) {
647 return NULL;
650 if (new_ctx == NULL) {
651 new_ctx = null_context;
654 tc = talloc_chunk_from_ptr(ptr);
656 if (new_ctx == NULL) {
657 if (tc->parent) {
658 _TLIST_REMOVE(tc->parent->child, tc);
659 if (tc->parent->child) {
660 tc->parent->child->parent = tc->parent;
662 } else {
663 if (tc->prev) tc->prev->next = tc->next;
664 if (tc->next) tc->next->prev = tc->prev;
667 tc->parent = tc->next = tc->prev = NULL;
668 return discard_const_p(void, ptr);
671 new_tc = talloc_chunk_from_ptr(new_ctx);
673 if (tc == new_tc) {
674 return discard_const_p(void, ptr);
677 if (tc->parent) {
678 _TLIST_REMOVE(tc->parent->child, tc);
679 if (tc->parent->child) {
680 tc->parent->child->parent = tc->parent;
682 } else {
683 if (tc->prev) tc->prev->next = tc->next;
684 if (tc->next) tc->next->prev = tc->prev;
687 tc->parent = new_tc;
688 if (new_tc->child) new_tc->child->parent = NULL;
689 _TLIST_ADD(new_tc->child, tc);
691 return discard_const_p(void, ptr);
695 return the total size of a talloc pool (subtree)
697 off_t talloc_total_size(const void *ptr)
699 off_t total = 0;
700 struct talloc_chunk *c, *tc;
702 if (ptr == NULL) {
703 ptr = null_context;
705 if (ptr == NULL) {
706 return 0;
709 tc = talloc_chunk_from_ptr(ptr);
711 total = tc->size;
712 for (c=tc->child;c;c=c->next) {
713 total += talloc_total_size(c+1);
715 return total;
719 return the total number of blocks in a talloc pool (subtree)
721 off_t talloc_total_blocks(const void *ptr)
723 off_t total = 0;
724 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
726 total++;
727 for (c=tc->child;c;c=c->next) {
728 total += talloc_total_blocks(c+1);
730 return total;
734 return the number of external references to a pointer
736 static int talloc_reference_count(const void *ptr)
738 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
739 struct talloc_reference_handle *h;
740 int ret = 0;
742 for (h=tc->refs;h;h=h->next) {
743 ret++;
745 return ret;
749 report on memory usage by all children of a pointer, giving a full tree view
751 void talloc_report_depth(const void *ptr, FILE *f, int depth)
753 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
755 for (c=tc->child;c;c=c->next) {
756 if (c->name == TALLOC_MAGIC_REFERENCE) {
757 struct talloc_reference_handle *handle = (void *)(c+1);
758 const char *name2 = talloc_get_name(handle->ptr);
759 fprintf(f, "%*sreference to: %s\n", depth*4, "", name2);
760 } else {
761 const char *name = talloc_get_name(c+1);
762 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n",
763 depth*4, "",
764 name,
765 (unsigned long)talloc_total_size(c+1),
766 (unsigned long)talloc_total_blocks(c+1),
767 talloc_reference_count(c+1));
768 talloc_report_depth(c+1, f, depth+1);
775 report on memory usage by all children of a pointer, giving a full tree view
777 void talloc_report_full(const void *ptr, FILE *f)
779 if (ptr == NULL) {
780 ptr = null_context;
782 if (ptr == NULL) return;
784 fprintf(f,"full talloc report on '%s' (total %lu bytes in %lu blocks)\n",
785 talloc_get_name(ptr),
786 (unsigned long)talloc_total_size(ptr),
787 (unsigned long)talloc_total_blocks(ptr));
789 talloc_report_depth(ptr, f, 1);
790 fflush(f);
794 report on memory usage by all children of a pointer
796 void talloc_report(const void *ptr, FILE *f)
798 struct talloc_chunk *c, *tc;
800 if (ptr == NULL) {
801 ptr = null_context;
803 if (ptr == NULL) return;
805 fprintf(f,"talloc report on '%s' (total %lu bytes in %lu blocks)\n",
806 talloc_get_name(ptr),
807 (unsigned long)talloc_total_size(ptr),
808 (unsigned long)talloc_total_blocks(ptr));
810 tc = talloc_chunk_from_ptr(ptr);
812 for (c=tc->child;c;c=c->next) {
813 fprintf(f, "\t%-30s contains %6lu bytes in %3lu blocks\n",
814 talloc_get_name(c+1),
815 (unsigned long)talloc_total_size(c+1),
816 (unsigned long)talloc_total_blocks(c+1));
818 fflush(f);
822 report on any memory hanging off the null context
824 static void talloc_report_null(void)
826 if (talloc_total_size(null_context) != 0) {
827 talloc_report(null_context, stderr);
832 report on any memory hanging off the null context
834 static void talloc_report_null_full(void)
836 if (talloc_total_size(null_context) != 0) {
837 talloc_report_full(null_context, stderr);
842 enable tracking of the NULL context
844 void talloc_enable_null_tracking(void)
846 if (null_context == NULL) {
847 null_context = talloc_named_const(NULL, 0, "null_context");
852 enable leak reporting on exit
854 void talloc_enable_leak_report(void)
856 talloc_enable_null_tracking();
857 atexit(talloc_report_null);
861 enable full leak reporting on exit
863 void talloc_enable_leak_report_full(void)
865 talloc_enable_null_tracking();
866 atexit(talloc_report_null_full);
870 talloc and zero memory.
872 void *_talloc_zero(const void *ctx, size_t size, const char *name)
874 void *p = talloc_named_const(ctx, size, name);
876 if (p) {
877 memset(p, '\0', size);
880 return p;
885 memdup with a talloc.
887 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
889 void *newp = talloc_named_const(t, size, name);
891 if (newp) {
892 memcpy(newp, p, size);
895 return newp;
899 strdup with a talloc
901 char *talloc_strdup(const void *t, const char *p)
903 char *ret;
904 if (!p) {
905 return NULL;
907 ret = talloc_memdup(t, p, strlen(p) + 1);
908 if (ret) {
909 talloc_set_name_const(ret, ret);
911 return ret;
915 strndup with a talloc
917 char *talloc_strndup(const void *t, const char *p, size_t n)
919 size_t len;
920 char *ret;
922 for (len=0; len<n && p[len]; len++) ;
924 ret = _talloc(t, len + 1);
925 if (!ret) { return NULL; }
926 memcpy(ret, p, len);
927 ret[len] = 0;
928 talloc_set_name_const(ret, ret);
929 return ret;
932 #ifndef VA_COPY
933 #ifdef HAVE_VA_COPY
934 #define VA_COPY(dest, src) va_copy(dest, src)
935 #elif defined(HAVE___VA_COPY)
936 #define VA_COPY(dest, src) __va_copy(dest, src)
937 #else
938 #define VA_COPY(dest, src) (dest) = (src)
939 #endif
940 #endif
942 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
944 int len;
945 char *ret;
946 va_list ap2;
948 VA_COPY(ap2, ap);
950 len = vsnprintf(NULL, 0, fmt, ap2);
952 ret = _talloc(t, len+1);
953 if (ret) {
954 VA_COPY(ap2, ap);
955 vsnprintf(ret, len+1, fmt, ap2);
956 talloc_set_name_const(ret, ret);
959 return ret;
964 Perform string formatting, and return a pointer to newly allocated
965 memory holding the result, inside a memory pool.
967 char *talloc_asprintf(const void *t, const char *fmt, ...)
969 va_list ap;
970 char *ret;
972 va_start(ap, fmt);
973 ret = talloc_vasprintf(t, fmt, ap);
974 va_end(ap);
975 return ret;
980 * Realloc @p s to append the formatted result of @p fmt and @p ap,
981 * and return @p s, which may have moved. Good for gradually
982 * accumulating output into a string buffer.
985 static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
987 static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
989 struct talloc_chunk *tc;
990 int len, s_len;
991 va_list ap2;
993 if (s == NULL) {
994 return talloc_vasprintf(NULL, fmt, ap);
997 tc = talloc_chunk_from_ptr(s);
999 VA_COPY(ap2, ap);
1001 s_len = tc->size - 1;
1002 len = vsnprintf(NULL, 0, fmt, ap2);
1004 s = talloc_realloc(NULL, s, char, s_len + len+1);
1005 if (!s) return NULL;
1007 VA_COPY(ap2, ap);
1009 vsnprintf(s+s_len, len+1, fmt, ap2);
1010 talloc_set_name_const(s, s);
1012 return s;
1016 Realloc @p s to append the formatted result of @p fmt and return @p
1017 s, which may have moved. Good for gradually accumulating output
1018 into a string buffer.
1020 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1022 va_list ap;
1024 va_start(ap, fmt);
1025 s = talloc_vasprintf_append(s, fmt, ap);
1026 va_end(ap);
1027 return s;
1031 alloc an array, checking for integer overflow in the array size
1033 void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1035 if (count >= MAX_TALLOC_SIZE/el_size) {
1036 return NULL;
1038 return talloc_named_const(ctx, el_size * count, name);
1042 alloc an zero array, checking for integer overflow in the array size
1044 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1046 if (count >= MAX_TALLOC_SIZE/el_size) {
1047 return NULL;
1049 return _talloc_zero(ctx, el_size * count, name);
1054 realloc an array, checking for integer overflow in the array size
1056 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1058 if (count >= MAX_TALLOC_SIZE/el_size) {
1059 return NULL;
1061 return _talloc_realloc(ctx, ptr, el_size * count, name);
1065 a function version of talloc_realloc(), so it can be passed as a function pointer
1066 to libraries that want a realloc function (a realloc function encapsulates
1067 all the basic capabilities of an allocation library, which is why this is useful)
1069 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1071 return _talloc_realloc(context, ptr, size, NULL);
1075 static void talloc_autofree(void)
1077 talloc_free(cleanup_context);
1078 cleanup_context = NULL;
1082 return a context which will be auto-freed on exit
1083 this is useful for reducing the noise in leak reports
1085 void *talloc_autofree_context(void)
1087 if (cleanup_context == NULL) {
1088 cleanup_context = talloc_named_const(NULL, 0, "autofree_context");
1089 atexit(talloc_autofree);
1091 return cleanup_context;
1094 size_t talloc_get_size(const void *context)
1096 struct talloc_chunk *tc;
1098 if (context == NULL)
1099 return 0;
1101 tc = talloc_chunk_from_ptr(context);
1103 return tc->size;