r10242: ognore generated *.po files
[Samba.git] / source / lib / talloc.c
blob15b0f4ea7d872e5b8dc8282127a1180c07a88805
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 talloc_destructor_t destructor;
98 const char *name;
99 union {
100 unsigned magic;
101 double align_dummy;
102 } u;
105 /* panic if we get a bad magic value */
106 static struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
108 struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, ptr)-1;
109 if (tc->u.magic != TALLOC_MAGIC) {
110 if (tc->u.magic == TALLOC_MAGIC_FREE) {
111 TALLOC_ABORT("Bad talloc magic value - double free");
112 } else {
113 TALLOC_ABORT("Bad talloc magic value - unknown value");
117 return tc;
120 /* hook into the front of the list */
121 #define _TLIST_ADD(list, p) \
122 do { \
123 if (!(list)) { \
124 (list) = (p); \
125 (p)->next = (p)->prev = NULL; \
126 } else { \
127 (list)->prev = (p); \
128 (p)->next = (list); \
129 (p)->prev = NULL; \
130 (list) = (p); \
132 } while (0)
134 /* remove an element from a list - element doesn't have to be in list. */
135 #define _TLIST_REMOVE(list, p) \
136 do { \
137 if ((p) == (list)) { \
138 (list) = (p)->next; \
139 if (list) (list)->prev = NULL; \
140 } else { \
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; \
145 } while (0)
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;
155 return tc->parent;
158 void *talloc_parent(const void *ptr)
160 struct talloc_chunk *tc = talloc_parent_chunk(ptr);
161 return (void *)(tc+1);
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) {
176 return NULL;
179 tc = malloc(sizeof(*tc)+size);
180 if (tc == NULL) return NULL;
182 tc->size = size;
183 tc->u.magic = TALLOC_MAGIC;
184 tc->destructor = NULL;
185 tc->child = NULL;
186 tc->name = NULL;
187 tc->refs = NULL;
189 if (context) {
190 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
192 tc->parent = parent;
194 if (parent->child) {
195 parent->child->parent = NULL;
198 _TLIST_ADD(parent->child, tc);
199 } else {
200 tc->next = tc->prev = tc->parent = NULL;
203 return (void *)(tc+1);
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(void *ptr)
232 struct talloc_reference_handle *handle = ptr;
233 struct talloc_chunk *tc1 = talloc_chunk_from_ptr(ptr);
234 struct talloc_chunk *tc2 = talloc_chunk_from_ptr(handle->ptr);
235 if (tc1->destructor != (talloc_destructor_t)-1) {
236 tc1->destructor = NULL;
238 _TLIST_REMOVE(tc2->refs, handle);
239 talloc_free(handle);
240 return 0;
244 make a secondary reference to a pointer, hanging off the given context.
245 the pointer remains valid until both the original caller and this given
246 context are freed.
248 the major use for this is when two different structures need to reference the
249 same underlying data, and you want to be able to free the two instances separately,
250 and in either order
252 void *talloc_reference(const void *context, const void *ptr)
254 struct talloc_chunk *tc;
255 struct talloc_reference_handle *handle;
256 if (ptr == NULL) return NULL;
258 tc = talloc_chunk_from_ptr(ptr);
259 handle = talloc_named_const(context, sizeof(*handle), TALLOC_MAGIC_REFERENCE);
261 if (handle == NULL) return NULL;
263 /* note that we hang the destructor off the handle, not the
264 main context as that allows the caller to still setup their
265 own destructor on the context if they want to */
266 talloc_set_destructor(handle, talloc_reference_destructor);
267 handle->ptr = discard_const_p(void, ptr);
268 _TLIST_ADD(tc->refs, handle);
269 return handle->ptr;
273 remove a secondary reference to a pointer. This undo's what
274 talloc_reference() has done. The context and pointer arguments
275 must match those given to a talloc_reference()
277 static int talloc_unreference(const void *context, const void *ptr)
279 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
280 struct talloc_reference_handle *h;
282 if (context == NULL) {
283 context = null_context;
286 for (h=tc->refs;h;h=h->next) {
287 struct talloc_chunk *p = talloc_parent_chunk(h);
288 if ((p==NULL && context==NULL) || p+1 == context) break;
290 if (h == NULL) {
291 return -1;
294 talloc_set_destructor(h, NULL);
295 _TLIST_REMOVE(tc->refs, h);
296 talloc_free(h);
297 return 0;
301 remove a specific parent context from a pointer. This is a more
302 controlled varient of talloc_free()
304 int talloc_unlink(const void *context, void *ptr)
306 struct talloc_chunk *tc_p, *new_p;
307 void *new_parent;
309 if (ptr == NULL) {
310 return -1;
313 if (context == NULL) {
314 context = null_context;
317 if (talloc_unreference(context, ptr) == 0) {
318 return 0;
321 if (context == NULL) {
322 if (talloc_parent_chunk(ptr) != NULL) {
323 return -1;
325 } else {
326 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
327 return -1;
331 tc_p = talloc_chunk_from_ptr(ptr);
333 if (tc_p->refs == NULL) {
334 return talloc_free(ptr);
337 new_p = talloc_parent_chunk(tc_p->refs);
338 if (new_p) {
339 new_parent = new_p+1;
340 } else {
341 new_parent = NULL;
344 if (talloc_unreference(new_parent, ptr) != 0) {
345 return -1;
348 talloc_steal(new_parent, ptr);
350 return 0;
354 add a name to an existing pointer - va_list version
356 static void talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
358 static void talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
360 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
361 tc->name = talloc_vasprintf(ptr, fmt, ap);
362 if (tc->name) {
363 talloc_set_name_const(tc->name, ".name");
368 add a name to an existing pointer
370 void talloc_set_name(const void *ptr, const char *fmt, ...)
372 va_list ap;
373 va_start(ap, fmt);
374 talloc_set_name_v(ptr, fmt, ap);
375 va_end(ap);
379 more efficient way to add a name to a pointer - the name must point to a
380 true string constant
382 void talloc_set_name_const(const void *ptr, const char *name)
384 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
385 tc->name = name;
389 create a named talloc pointer. Any talloc pointer can be named, and
390 talloc_named() operates just like talloc() except that it allows you
391 to name the pointer.
393 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
395 va_list ap;
396 void *ptr;
398 ptr = _talloc(context, size);
399 if (ptr == NULL) return NULL;
401 va_start(ap, fmt);
402 talloc_set_name_v(ptr, fmt, ap);
403 va_end(ap);
405 return ptr;
409 create a named talloc pointer. Any talloc pointer can be named, and
410 talloc_named() operates just like talloc() except that it allows you
411 to name the pointer.
413 void *talloc_named_const(const void *context, size_t size, const char *name)
415 void *ptr;
417 ptr = _talloc(context, size);
418 if (ptr == NULL) {
419 return NULL;
422 talloc_set_name_const(ptr, name);
424 return ptr;
428 return the name of a talloc ptr, or "UNNAMED"
430 const char *talloc_get_name(const void *ptr)
432 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
433 if (tc->name == TALLOC_MAGIC_REFERENCE) {
434 return ".reference";
436 if (tc->name) {
437 return tc->name;
439 return "UNNAMED";
444 check if a pointer has the given name. If it does, return the pointer,
445 otherwise return NULL
447 void *talloc_check_name(const void *ptr, const char *name)
449 const char *pname;
450 if (ptr == NULL) return NULL;
451 pname = talloc_get_name(ptr);
452 if (pname == name || strcmp(pname, name) == 0) {
453 return discard_const_p(void, ptr);
455 return NULL;
460 this is for compatibility with older versions of talloc
462 void *talloc_init(const char *fmt, ...)
464 va_list ap;
465 void *ptr;
467 ptr = _talloc(NULL, 0);
468 if (ptr == NULL) return NULL;
470 va_start(ap, fmt);
471 talloc_set_name_v(ptr, fmt, ap);
472 va_end(ap);
474 return ptr;
478 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
479 should probably not be used in new code. It's in here to keep the talloc
480 code consistent across Samba 3 and 4.
482 void talloc_free_children(void *ptr)
484 struct talloc_chunk *tc;
486 if (ptr == NULL) {
487 return;
490 tc = talloc_chunk_from_ptr(ptr);
492 while (tc->child) {
493 /* we need to work out who will own an abandoned child
494 if it cannot be freed. In priority order, the first
495 choice is owner of any remaining reference to this
496 pointer, the second choice is our parent, and the
497 final choice is the null context. */
498 void *child = tc->child+1;
499 const void *new_parent = null_context;
500 if (tc->child->refs) {
501 struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
502 if (p) new_parent = p+1;
504 if (talloc_free(child) == -1) {
505 if (new_parent == null_context) {
506 struct talloc_chunk *p = talloc_parent_chunk(ptr);
507 if (p) new_parent = p+1;
509 talloc_steal(new_parent, child);
515 free a talloc pointer. This also frees all child pointers of this
516 pointer recursively
518 return 0 if the memory is actually freed, otherwise -1. The memory
519 will not be freed if the ref_count is > 1 or the destructor (if
520 any) returns non-zero
522 int talloc_free(void *ptr)
524 struct talloc_chunk *tc;
526 if (ptr == NULL) {
527 return -1;
530 tc = talloc_chunk_from_ptr(ptr);
532 if (tc->refs) {
533 talloc_reference_destructor(tc->refs);
534 return -1;
537 if (tc->destructor) {
538 talloc_destructor_t d = tc->destructor;
539 if (d == (talloc_destructor_t)-1) {
540 return -1;
542 tc->destructor = (talloc_destructor_t)-1;
543 if (d(ptr) == -1) {
544 tc->destructor = d;
545 return -1;
547 tc->destructor = NULL;
550 talloc_free_children(ptr);
552 if (tc->parent) {
553 _TLIST_REMOVE(tc->parent->child, tc);
554 if (tc->parent->child) {
555 tc->parent->child->parent = tc->parent;
557 } else {
558 if (tc->prev) tc->prev->next = tc->next;
559 if (tc->next) tc->next->prev = tc->prev;
562 tc->u.magic = TALLOC_MAGIC_FREE;
564 free(tc);
565 return 0;
571 A talloc version of realloc. The context argument is only used if
572 ptr is NULL
574 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
576 struct talloc_chunk *tc;
577 void *new_ptr;
579 /* size zero is equivalent to free() */
580 if (size == 0) {
581 talloc_free(ptr);
582 return NULL;
585 if (size >= MAX_TALLOC_SIZE) {
586 return NULL;
589 /* realloc(NULL) is equavalent to malloc() */
590 if (ptr == NULL) {
591 return talloc_named_const(context, size, name);
594 tc = talloc_chunk_from_ptr(ptr);
596 /* don't allow realloc on referenced pointers */
597 if (tc->refs) {
598 return NULL;
601 /* by resetting magic we catch users of the old memory */
602 tc->u.magic = TALLOC_MAGIC_FREE;
604 #if ALWAYS_REALLOC
605 new_ptr = malloc(size + sizeof(*tc));
606 if (new_ptr) {
607 memcpy(new_ptr, tc, tc->size + sizeof(*tc));
608 free(tc);
610 #else
611 new_ptr = realloc(tc, size + sizeof(*tc));
612 #endif
613 if (!new_ptr) {
614 tc->u.magic = TALLOC_MAGIC;
615 return NULL;
618 tc = new_ptr;
619 tc->u.magic = TALLOC_MAGIC;
620 if (tc->parent) {
621 tc->parent->child = new_ptr;
623 if (tc->child) {
624 tc->child->parent = new_ptr;
627 if (tc->prev) {
628 tc->prev->next = tc;
630 if (tc->next) {
631 tc->next->prev = tc;
634 tc->size = size;
635 talloc_set_name_const(tc+1, name);
637 return (void *)(tc+1);
641 move a lump of memory from one talloc context to another return the
642 ptr on success, or NULL if it could not be transferred.
643 passing NULL as ptr will always return NULL with no side effects.
645 void *talloc_steal(const void *new_ctx, const void *ptr)
647 struct talloc_chunk *tc, *new_tc;
649 if (!ptr) {
650 return NULL;
653 if (new_ctx == NULL) {
654 new_ctx = null_context;
657 tc = talloc_chunk_from_ptr(ptr);
659 if (new_ctx == NULL) {
660 if (tc->parent) {
661 _TLIST_REMOVE(tc->parent->child, tc);
662 if (tc->parent->child) {
663 tc->parent->child->parent = tc->parent;
665 } else {
666 if (tc->prev) tc->prev->next = tc->next;
667 if (tc->next) tc->next->prev = tc->prev;
670 tc->parent = tc->next = tc->prev = NULL;
671 return discard_const_p(void, ptr);
674 new_tc = talloc_chunk_from_ptr(new_ctx);
676 if (tc == new_tc) {
677 return discard_const_p(void, ptr);
680 if (tc->parent) {
681 _TLIST_REMOVE(tc->parent->child, tc);
682 if (tc->parent->child) {
683 tc->parent->child->parent = tc->parent;
685 } else {
686 if (tc->prev) tc->prev->next = tc->next;
687 if (tc->next) tc->next->prev = tc->prev;
690 tc->parent = new_tc;
691 if (new_tc->child) new_tc->child->parent = NULL;
692 _TLIST_ADD(new_tc->child, tc);
694 return discard_const_p(void, ptr);
698 return the total size of a talloc pool (subtree)
700 off_t talloc_total_size(const void *ptr)
702 off_t total = 0;
703 struct talloc_chunk *c, *tc;
705 if (ptr == NULL) {
706 ptr = null_context;
708 if (ptr == NULL) {
709 return 0;
712 tc = talloc_chunk_from_ptr(ptr);
714 total = tc->size;
715 for (c=tc->child;c;c=c->next) {
716 total += talloc_total_size(c+1);
718 return total;
722 return the total number of blocks in a talloc pool (subtree)
724 off_t talloc_total_blocks(const void *ptr)
726 off_t total = 0;
727 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
729 total++;
730 for (c=tc->child;c;c=c->next) {
731 total += talloc_total_blocks(c+1);
733 return total;
737 return the number of external references to a pointer
739 static int talloc_reference_count(const void *ptr)
741 struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
742 struct talloc_reference_handle *h;
743 int ret = 0;
745 for (h=tc->refs;h;h=h->next) {
746 ret++;
748 return ret;
752 report on memory usage by all children of a pointer, giving a full tree view
754 void talloc_report_depth(const void *ptr, FILE *f, int depth)
756 struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
758 for (c=tc->child;c;c=c->next) {
759 if (c->name == TALLOC_MAGIC_REFERENCE) {
760 struct talloc_reference_handle *handle = (void *)(c+1);
761 const char *name2 = talloc_get_name(handle->ptr);
762 fprintf(f, "%*sreference to: %s\n", depth*4, "", name2);
763 } else {
764 const char *name = talloc_get_name(c+1);
765 fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n",
766 depth*4, "",
767 name,
768 (unsigned long)talloc_total_size(c+1),
769 (unsigned long)talloc_total_blocks(c+1),
770 talloc_reference_count(c+1));
771 talloc_report_depth(c+1, f, depth+1);
778 report on memory usage by all children of a pointer, giving a full tree view
780 void talloc_report_full(const void *ptr, FILE *f)
782 if (ptr == NULL) {
783 ptr = null_context;
785 if (ptr == NULL) return;
787 fprintf(f,"full talloc report on '%s' (total %lu bytes in %lu blocks)\n",
788 talloc_get_name(ptr),
789 (unsigned long)talloc_total_size(ptr),
790 (unsigned long)talloc_total_blocks(ptr));
792 talloc_report_depth(ptr, f, 1);
793 fflush(f);
797 report on memory usage by all children of a pointer
799 void talloc_report(const void *ptr, FILE *f)
801 struct talloc_chunk *c, *tc;
803 if (ptr == NULL) {
804 ptr = null_context;
806 if (ptr == NULL) return;
808 fprintf(f,"talloc report on '%s' (total %lu bytes in %lu blocks)\n",
809 talloc_get_name(ptr),
810 (unsigned long)talloc_total_size(ptr),
811 (unsigned long)talloc_total_blocks(ptr));
813 tc = talloc_chunk_from_ptr(ptr);
815 for (c=tc->child;c;c=c->next) {
816 fprintf(f, "\t%-30s contains %6lu bytes in %3lu blocks\n",
817 talloc_get_name(c+1),
818 (unsigned long)talloc_total_size(c+1),
819 (unsigned long)talloc_total_blocks(c+1));
821 fflush(f);
825 report on any memory hanging off the null context
827 static void talloc_report_null(void)
829 if (talloc_total_size(null_context) != 0) {
830 talloc_report(null_context, stderr);
835 report on any memory hanging off the null context
837 static void talloc_report_null_full(void)
839 if (talloc_total_size(null_context) != 0) {
840 talloc_report_full(null_context, stderr);
845 enable tracking of the NULL context
847 void talloc_enable_null_tracking(void)
849 if (null_context == NULL) {
850 null_context = talloc_named_const(NULL, 0, "null_context");
855 enable leak reporting on exit
857 void talloc_enable_leak_report(void)
859 talloc_enable_null_tracking();
860 atexit(talloc_report_null);
864 enable full leak reporting on exit
866 void talloc_enable_leak_report_full(void)
868 talloc_enable_null_tracking();
869 atexit(talloc_report_null_full);
873 talloc and zero memory.
875 void *_talloc_zero(const void *ctx, size_t size, const char *name)
877 void *p = talloc_named_const(ctx, size, name);
879 if (p) {
880 memset(p, '\0', size);
883 return p;
888 memdup with a talloc.
890 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
892 void *newp = talloc_named_const(t, size, name);
894 if (newp) {
895 memcpy(newp, p, size);
898 return newp;
902 strdup with a talloc
904 char *talloc_strdup(const void *t, const char *p)
906 char *ret;
907 if (!p) {
908 return NULL;
910 ret = talloc_memdup(t, p, strlen(p) + 1);
911 if (ret) {
912 talloc_set_name_const(ret, ret);
914 return ret;
918 strndup with a talloc
920 char *talloc_strndup(const void *t, const char *p, size_t n)
922 size_t len;
923 char *ret;
925 for (len=0; len<n && p[len]; len++) ;
927 ret = _talloc(t, len + 1);
928 if (!ret) { return NULL; }
929 memcpy(ret, p, len);
930 ret[len] = 0;
931 talloc_set_name_const(ret, ret);
932 return ret;
935 #ifndef VA_COPY
936 #ifdef HAVE_VA_COPY
937 #define VA_COPY(dest, src) va_copy(dest, src)
938 #elif defined(HAVE___VA_COPY)
939 #define VA_COPY(dest, src) __va_copy(dest, src)
940 #else
941 #define VA_COPY(dest, src) (dest) = (src)
942 #endif
943 #endif
945 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
947 int len;
948 char *ret;
949 va_list ap2;
951 VA_COPY(ap2, ap);
953 len = vsnprintf(NULL, 0, fmt, ap2);
955 ret = _talloc(t, len+1);
956 if (ret) {
957 VA_COPY(ap2, ap);
958 vsnprintf(ret, len+1, fmt, ap2);
959 talloc_set_name_const(ret, ret);
962 return ret;
967 Perform string formatting, and return a pointer to newly allocated
968 memory holding the result, inside a memory pool.
970 char *talloc_asprintf(const void *t, const char *fmt, ...)
972 va_list ap;
973 char *ret;
975 va_start(ap, fmt);
976 ret = talloc_vasprintf(t, fmt, ap);
977 va_end(ap);
978 return ret;
983 * Realloc @p s to append the formatted result of @p fmt and @p ap,
984 * and return @p s, which may have moved. Good for gradually
985 * accumulating output into a string buffer.
988 static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
990 static char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
992 struct talloc_chunk *tc;
993 int len, s_len;
994 va_list ap2;
996 if (s == NULL) {
997 return talloc_vasprintf(NULL, fmt, ap);
1000 tc = talloc_chunk_from_ptr(s);
1002 VA_COPY(ap2, ap);
1004 s_len = tc->size - 1;
1005 len = vsnprintf(NULL, 0, fmt, ap2);
1007 s = talloc_realloc(NULL, s, char, s_len + len+1);
1008 if (!s) return NULL;
1010 VA_COPY(ap2, ap);
1012 vsnprintf(s+s_len, len+1, fmt, ap2);
1013 talloc_set_name_const(s, s);
1015 return s;
1019 Realloc @p s to append the formatted result of @p fmt and return @p
1020 s, which may have moved. Good for gradually accumulating output
1021 into a string buffer.
1023 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1025 va_list ap;
1027 va_start(ap, fmt);
1028 s = talloc_vasprintf_append(s, fmt, ap);
1029 va_end(ap);
1030 return s;
1034 alloc an array, checking for integer overflow in the array size
1036 void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1038 if (count >= MAX_TALLOC_SIZE/el_size) {
1039 return NULL;
1041 return talloc_named_const(ctx, el_size * count, name);
1045 alloc an zero array, checking for integer overflow in the array size
1047 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1049 if (count >= MAX_TALLOC_SIZE/el_size) {
1050 return NULL;
1052 return _talloc_zero(ctx, el_size * count, name);
1057 realloc an array, checking for integer overflow in the array size
1059 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1061 if (count >= MAX_TALLOC_SIZE/el_size) {
1062 return NULL;
1064 return _talloc_realloc(ctx, ptr, el_size * count, name);
1068 a function version of talloc_realloc(), so it can be passed as a function pointer
1069 to libraries that want a realloc function (a realloc function encapsulates
1070 all the basic capabilities of an allocation library, which is why this is useful)
1072 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1074 return _talloc_realloc(context, ptr, size, NULL);
1078 static void talloc_autofree(void)
1080 talloc_free(cleanup_context);
1081 cleanup_context = NULL;
1085 return a context which will be auto-freed on exit
1086 this is useful for reducing the noise in leak reports
1088 void *talloc_autofree_context(void)
1090 if (cleanup_context == NULL) {
1091 cleanup_context = talloc_named_const(NULL, 0, "autofree_context");
1092 atexit(talloc_autofree);
1094 return cleanup_context;
1097 size_t talloc_get_size(const void *context)
1099 struct talloc_chunk *tc;
1101 if (context == NULL)
1102 return 0;
1104 tc = talloc_chunk_from_ptr(context);
1106 return tc->size;