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
;
89 struct talloc_reference_handle
{
90 struct talloc_reference_handle
*next
, *prev
;
94 typedef int (*talloc_destructor_t
)(void *);
97 struct talloc_chunk
*next
, *prev
;
98 struct talloc_chunk
*parent
, *child
;
99 struct talloc_reference_handle
*refs
;
100 talloc_destructor_t destructor
;
106 /* 16 byte alignment seems to keep everyone happy */
107 #define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
108 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
110 /* panic if we get a bad magic value */
111 static struct talloc_chunk
*talloc_chunk_from_ptr(const void *ptr
)
113 const char *pp
= ptr
;
114 struct talloc_chunk
*tc
= discard_const_p(struct talloc_chunk
, pp
- TC_HDR_SIZE
);
115 if ((tc
->flags
& ~0xF) != TALLOC_MAGIC
) {
116 TALLOC_ABORT("Bad talloc magic value - unknown value");
118 if (tc
->flags
& TALLOC_FLAG_FREE
) {
119 TALLOC_ABORT("Bad talloc magic value - double free");
124 /* hook into the front of the list */
125 #define _TLIST_ADD(list, p) \
129 (p)->next = (p)->prev = NULL; \
131 (list)->prev = (p); \
132 (p)->next = (list); \
138 /* remove an element from a list - element doesn't have to be in list. */
139 #define _TLIST_REMOVE(list, p) \
141 if ((p) == (list)) { \
142 (list) = (p)->next; \
143 if (list) (list)->prev = NULL; \
145 if ((p)->prev) (p)->prev->next = (p)->next; \
146 if ((p)->next) (p)->next->prev = (p)->prev; \
148 if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
153 return the parent chunk of a pointer
155 static struct talloc_chunk
*talloc_parent_chunk(const void *ptr
)
157 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
158 while (tc
->prev
) tc
=tc
->prev
;
162 void *talloc_parent(const void *ptr
)
164 struct talloc_chunk
*tc
= talloc_parent_chunk(ptr
);
165 return tc
? TC_PTR_FROM_CHUNK(tc
) : NULL
;
169 Allocate a bit of memory as a child of an existing pointer
171 void *_talloc(const void *context
, size_t size
)
173 struct talloc_chunk
*tc
;
175 if (context
== NULL
) {
176 context
= null_context
;
179 if (size
>= MAX_TALLOC_SIZE
) {
183 tc
= malloc(TC_HDR_SIZE
+size
);
184 if (tc
== NULL
) return NULL
;
187 tc
->flags
= TALLOC_MAGIC
;
188 tc
->destructor
= NULL
;
194 struct talloc_chunk
*parent
= talloc_chunk_from_ptr(context
);
199 parent
->child
->parent
= NULL
;
202 _TLIST_ADD(parent
->child
, tc
);
204 tc
->next
= tc
->prev
= tc
->parent
= NULL
;
207 return TC_PTR_FROM_CHUNK(tc
);
212 setup a destructor to be called on free of a pointer
213 the destructor should return 0 on success, or -1 on failure.
214 if the destructor fails then the free is failed, and the memory can
215 be continued to be used
217 void talloc_set_destructor(const void *ptr
, int (*destructor
)(void *))
219 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
220 tc
->destructor
= destructor
;
224 increase the reference count on a piece of memory.
226 void talloc_increase_ref_count(const void *ptr
)
228 talloc_reference(null_context
, ptr
);
232 helper for talloc_reference()
234 static int talloc_reference_destructor(void *ptr
)
236 struct talloc_reference_handle
*handle
= ptr
;
237 struct talloc_chunk
*tc1
= talloc_chunk_from_ptr(ptr
);
238 struct talloc_chunk
*tc2
= talloc_chunk_from_ptr(handle
->ptr
);
239 if (tc1
->destructor
!= (talloc_destructor_t
)-1) {
240 tc1
->destructor
= NULL
;
242 _TLIST_REMOVE(tc2
->refs
, handle
);
248 make a secondary reference to a pointer, hanging off the given context.
249 the pointer remains valid until both the original caller and this given
252 the major use for this is when two different structures need to reference the
253 same underlying data, and you want to be able to free the two instances separately,
256 void *talloc_reference(const void *context
, const void *ptr
)
258 struct talloc_chunk
*tc
;
259 struct talloc_reference_handle
*handle
;
260 if (ptr
== NULL
) return NULL
;
262 tc
= talloc_chunk_from_ptr(ptr
);
263 handle
= talloc_named_const(context
, sizeof(*handle
), TALLOC_MAGIC_REFERENCE
);
265 if (handle
== NULL
) return NULL
;
267 /* note that we hang the destructor off the handle, not the
268 main context as that allows the caller to still setup their
269 own destructor on the context if they want to */
270 talloc_set_destructor(handle
, talloc_reference_destructor
);
271 handle
->ptr
= discard_const_p(void, ptr
);
272 _TLIST_ADD(tc
->refs
, handle
);
277 remove a secondary reference to a pointer. This undo's what
278 talloc_reference() has done. The context and pointer arguments
279 must match those given to a talloc_reference()
281 static int talloc_unreference(const void *context
, const void *ptr
)
283 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
284 struct talloc_reference_handle
*h
;
286 if (context
== NULL
) {
287 context
= null_context
;
290 for (h
=tc
->refs
;h
;h
=h
->next
) {
291 struct talloc_chunk
*p
= talloc_parent_chunk(h
);
293 if (context
== NULL
) break;
294 } else if (TC_PTR_FROM_CHUNK(p
) == context
) {
302 talloc_set_destructor(h
, NULL
);
303 _TLIST_REMOVE(tc
->refs
, h
);
309 remove a specific parent context from a pointer. This is a more
310 controlled varient of talloc_free()
312 int talloc_unlink(const void *context
, void *ptr
)
314 struct talloc_chunk
*tc_p
, *new_p
;
321 if (context
== NULL
) {
322 context
= null_context
;
325 if (talloc_unreference(context
, ptr
) == 0) {
329 if (context
== NULL
) {
330 if (talloc_parent_chunk(ptr
) != NULL
) {
334 if (talloc_chunk_from_ptr(context
) != talloc_parent_chunk(ptr
)) {
339 tc_p
= talloc_chunk_from_ptr(ptr
);
341 if (tc_p
->refs
== NULL
) {
342 return talloc_free(ptr
);
345 new_p
= talloc_parent_chunk(tc_p
->refs
);
347 new_parent
= TC_PTR_FROM_CHUNK(new_p
);
352 if (talloc_unreference(new_parent
, ptr
) != 0) {
356 talloc_steal(new_parent
, ptr
);
362 add a name to an existing pointer - va_list version
364 static void talloc_set_name_v(const void *ptr
, const char *fmt
, va_list ap
) PRINTF_ATTRIBUTE(2,0);
366 static void talloc_set_name_v(const void *ptr
, const char *fmt
, va_list ap
)
368 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
369 tc
->name
= talloc_vasprintf(ptr
, fmt
, ap
);
371 talloc_set_name_const(tc
->name
, ".name");
376 add a name to an existing pointer
378 void talloc_set_name(const void *ptr
, const char *fmt
, ...)
382 talloc_set_name_v(ptr
, fmt
, ap
);
387 more efficient way to add a name to a pointer - the name must point to a
390 void talloc_set_name_const(const void *ptr
, const char *name
)
392 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
397 create a named talloc pointer. Any talloc pointer can be named, and
398 talloc_named() operates just like talloc() except that it allows you
401 void *talloc_named(const void *context
, size_t size
, const char *fmt
, ...)
406 ptr
= _talloc(context
, size
);
407 if (ptr
== NULL
) return NULL
;
410 talloc_set_name_v(ptr
, fmt
, ap
);
417 create a named talloc pointer. Any talloc pointer can be named, and
418 talloc_named() operates just like talloc() except that it allows you
421 void *talloc_named_const(const void *context
, size_t size
, const char *name
)
425 ptr
= _talloc(context
, size
);
430 talloc_set_name_const(ptr
, name
);
436 return the name of a talloc ptr, or "UNNAMED"
438 const char *talloc_get_name(const void *ptr
)
440 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
441 if (tc
->name
== TALLOC_MAGIC_REFERENCE
) {
452 check if a pointer has the given name. If it does, return the pointer,
453 otherwise return NULL
455 void *talloc_check_name(const void *ptr
, const char *name
)
458 if (ptr
== NULL
) return NULL
;
459 pname
= talloc_get_name(ptr
);
460 if (pname
== name
|| strcmp(pname
, name
) == 0) {
461 return discard_const_p(void, ptr
);
468 this is for compatibility with older versions of talloc
470 void *talloc_init(const char *fmt
, ...)
475 talloc_enable_null_tracking();
477 ptr
= _talloc(NULL
, 0);
478 if (ptr
== NULL
) return NULL
;
481 talloc_set_name_v(ptr
, fmt
, ap
);
488 this is a replacement for the Samba3 talloc_destroy_pool functionality. It
489 should probably not be used in new code. It's in here to keep the talloc
490 code consistent across Samba 3 and 4.
492 void talloc_free_children(void *ptr
)
494 struct talloc_chunk
*tc
;
500 tc
= talloc_chunk_from_ptr(ptr
);
503 /* we need to work out who will own an abandoned child
504 if it cannot be freed. In priority order, the first
505 choice is owner of any remaining reference to this
506 pointer, the second choice is our parent, and the
507 final choice is the null context. */
508 void *child
= TC_PTR_FROM_CHUNK(tc
->child
);
509 const void *new_parent
= null_context
;
510 if (tc
->child
->refs
) {
511 struct talloc_chunk
*p
= talloc_parent_chunk(tc
->child
->refs
);
512 if (p
) new_parent
= TC_PTR_FROM_CHUNK(p
);
514 if (talloc_free(child
) == -1) {
515 if (new_parent
== null_context
) {
516 struct talloc_chunk
*p
= talloc_parent_chunk(ptr
);
517 if (p
) new_parent
= TC_PTR_FROM_CHUNK(p
);
519 talloc_steal(new_parent
, child
);
525 free a talloc pointer. This also frees all child pointers of this
528 return 0 if the memory is actually freed, otherwise -1. The memory
529 will not be freed if the ref_count is > 1 or the destructor (if
530 any) returns non-zero
532 int talloc_free(void *ptr
)
534 struct talloc_chunk
*tc
;
540 tc
= talloc_chunk_from_ptr(ptr
);
544 struct talloc_reference_handle
*handle
= tc
->refs
;
545 is_child
= talloc_is_parent(handle
, handle
->ptr
);
546 talloc_reference_destructor(tc
->refs
);
548 return talloc_free(ptr
);
553 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
554 /* we have a free loop - stop looping */
558 if (tc
->destructor
) {
559 talloc_destructor_t d
= tc
->destructor
;
560 if (d
== (talloc_destructor_t
)-1) {
563 tc
->destructor
= (talloc_destructor_t
)-1;
568 tc
->destructor
= NULL
;
571 tc
->flags
|= TALLOC_FLAG_LOOP
;
573 talloc_free_children(ptr
);
576 _TLIST_REMOVE(tc
->parent
->child
, tc
);
577 if (tc
->parent
->child
) {
578 tc
->parent
->child
->parent
= tc
->parent
;
581 if (tc
->prev
) tc
->prev
->next
= tc
->next
;
582 if (tc
->next
) tc
->next
->prev
= tc
->prev
;
585 tc
->flags
|= TALLOC_FLAG_FREE
;
594 A talloc version of realloc. The context argument is only used if
597 void *_talloc_realloc(const void *context
, void *ptr
, size_t size
, const char *name
)
599 struct talloc_chunk
*tc
;
602 /* size zero is equivalent to free() */
608 if (size
>= MAX_TALLOC_SIZE
) {
612 /* realloc(NULL) is equavalent to malloc() */
614 return talloc_named_const(context
, size
, name
);
617 tc
= talloc_chunk_from_ptr(ptr
);
619 /* don't allow realloc on referenced pointers */
624 /* by resetting magic we catch users of the old memory */
625 tc
->flags
|= TALLOC_FLAG_FREE
;
628 new_ptr
= malloc(size
+ TC_HDR_SIZE
);
630 memcpy(new_ptr
, tc
, tc
->size
+ TC_HDR_SIZE
);
634 new_ptr
= realloc(tc
, size
+ TC_HDR_SIZE
);
637 tc
->flags
&= ~TALLOC_FLAG_FREE
;
642 tc
->flags
&= ~TALLOC_FLAG_FREE
;
644 tc
->parent
->child
= new_ptr
;
647 tc
->child
->parent
= new_ptr
;
658 talloc_set_name_const(TC_PTR_FROM_CHUNK(tc
), name
);
660 return TC_PTR_FROM_CHUNK(tc
);
664 move a lump of memory from one talloc context to another return the
665 ptr on success, or NULL if it could not be transferred.
666 passing NULL as ptr will always return NULL with no side effects.
668 void *talloc_steal(const void *new_ctx
, const void *ptr
)
670 struct talloc_chunk
*tc
, *new_tc
;
676 if (new_ctx
== NULL
) {
677 new_ctx
= null_context
;
680 tc
= talloc_chunk_from_ptr(ptr
);
682 if (new_ctx
== NULL
) {
684 _TLIST_REMOVE(tc
->parent
->child
, tc
);
685 if (tc
->parent
->child
) {
686 tc
->parent
->child
->parent
= tc
->parent
;
689 if (tc
->prev
) tc
->prev
->next
= tc
->next
;
690 if (tc
->next
) tc
->next
->prev
= tc
->prev
;
693 tc
->parent
= tc
->next
= tc
->prev
= NULL
;
694 return discard_const_p(void, ptr
);
697 new_tc
= talloc_chunk_from_ptr(new_ctx
);
699 if (tc
== new_tc
|| tc
->parent
== new_tc
) {
700 return discard_const_p(void, ptr
);
704 _TLIST_REMOVE(tc
->parent
->child
, tc
);
705 if (tc
->parent
->child
) {
706 tc
->parent
->child
->parent
= tc
->parent
;
709 if (tc
->prev
) tc
->prev
->next
= tc
->next
;
710 if (tc
->next
) tc
->next
->prev
= tc
->prev
;
714 if (new_tc
->child
) new_tc
->child
->parent
= NULL
;
715 _TLIST_ADD(new_tc
->child
, tc
);
717 return discard_const_p(void, ptr
);
721 return the total size of a talloc pool (subtree)
723 off_t
talloc_total_size(const void *ptr
)
726 struct talloc_chunk
*c
, *tc
;
735 tc
= talloc_chunk_from_ptr(ptr
);
737 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
741 tc
->flags
|= TALLOC_FLAG_LOOP
;
744 for (c
=tc
->child
;c
;c
=c
->next
) {
745 total
+= talloc_total_size(TC_PTR_FROM_CHUNK(c
));
748 tc
->flags
&= ~TALLOC_FLAG_LOOP
;
754 return the total number of blocks in a talloc pool (subtree)
756 off_t
talloc_total_blocks(const void *ptr
)
759 struct talloc_chunk
*c
, *tc
= talloc_chunk_from_ptr(ptr
);
761 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
765 tc
->flags
|= TALLOC_FLAG_LOOP
;
768 for (c
=tc
->child
;c
;c
=c
->next
) {
769 total
+= talloc_total_blocks(TC_PTR_FROM_CHUNK(c
));
772 tc
->flags
&= ~TALLOC_FLAG_LOOP
;
778 return the number of external references to a pointer
780 static int talloc_reference_count(const void *ptr
)
782 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
783 struct talloc_reference_handle
*h
;
786 for (h
=tc
->refs
;h
;h
=h
->next
) {
793 report on memory usage by all children of a pointer, giving a full tree view
795 void talloc_report_depth(const void *ptr
, FILE *f
, int depth
)
797 struct talloc_chunk
*c
, *tc
= talloc_chunk_from_ptr(ptr
);
799 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
803 tc
->flags
|= TALLOC_FLAG_LOOP
;
805 for (c
=tc
->child
;c
;c
=c
->next
) {
806 if (c
->name
== TALLOC_MAGIC_REFERENCE
) {
807 struct talloc_reference_handle
*handle
= TC_PTR_FROM_CHUNK(c
);
808 const char *name2
= talloc_get_name(handle
->ptr
);
809 fprintf(f
, "%*sreference to: %s\n", depth
*4, "", name2
);
811 const char *name
= talloc_get_name(TC_PTR_FROM_CHUNK(c
));
812 fprintf(f
, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n",
815 (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c
)),
816 (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c
)),
817 talloc_reference_count(TC_PTR_FROM_CHUNK(c
)));
818 talloc_report_depth(TC_PTR_FROM_CHUNK(c
), f
, depth
+1);
821 tc
->flags
&= ~TALLOC_FLAG_LOOP
;
825 report on memory usage by all children of a pointer, giving a full tree view
827 void talloc_report_full(const void *ptr
, FILE *f
)
832 if (ptr
== NULL
) return;
834 fprintf(f
,"full talloc report on '%s' (total %lu bytes in %lu blocks)\n",
835 talloc_get_name(ptr
),
836 (unsigned long)talloc_total_size(ptr
),
837 (unsigned long)talloc_total_blocks(ptr
));
839 talloc_report_depth(ptr
, f
, 1);
844 report on memory usage by all children of a pointer
846 void talloc_report(const void *ptr
, FILE *f
)
848 struct talloc_chunk
*c
, *tc
;
853 if (ptr
== NULL
) return;
855 fprintf(f
,"talloc report on '%s' (total %lu bytes in %lu blocks)\n",
856 talloc_get_name(ptr
),
857 (unsigned long)talloc_total_size(ptr
),
858 (unsigned long)talloc_total_blocks(ptr
));
860 tc
= talloc_chunk_from_ptr(ptr
);
862 for (c
=tc
->child
;c
;c
=c
->next
) {
863 fprintf(f
, "\t%-30s contains %6lu bytes in %3lu blocks\n",
864 talloc_get_name(TC_PTR_FROM_CHUNK(c
)),
865 (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c
)),
866 (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c
)));
872 report on any memory hanging off the null context
874 static void talloc_report_null(void)
876 if (talloc_total_size(null_context
) != 0) {
877 talloc_report(null_context
, stderr
);
882 report on any memory hanging off the null context
884 static void talloc_report_null_full(void)
886 if (talloc_total_size(null_context
) != 0) {
887 talloc_report_full(null_context
, stderr
);
892 free allocated global memory
895 void talloc_nc_free(void)
898 talloc_free( (void*)null_context
);
902 enable tracking of the NULL context
904 void talloc_enable_null_tracking(void)
906 if (null_context
== NULL
) {
907 null_context
= talloc_named_const(NULL
, 0, "null_context");
912 /* Ugly calls to Samba-specific sprintf_append... JRA. */
915 report on memory usage by all children of a pointer, giving a full tree view
917 static void talloc_report_depth_str(const void *ptr
, char **pps
, ssize_t
*plen
, size_t *pbuflen
, int depth
)
919 struct talloc_chunk
*c
, *tc
= talloc_chunk_from_ptr(ptr
);
921 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
925 tc
->flags
|= TALLOC_FLAG_LOOP
;
927 for (c
=tc
->child
;c
;c
=c
->next
) {
928 if (c
->name
== TALLOC_MAGIC_REFERENCE
) {
929 struct talloc_reference_handle
*handle
= TC_PTR_FROM_CHUNK(c
);
930 const char *name2
= talloc_get_name(handle
->ptr
);
932 sprintf_append(NULL
, pps
, plen
, pbuflen
,
933 "%*sreference to: %s\n", depth
*4, "", name2
);
936 const char *name
= talloc_get_name(TC_PTR_FROM_CHUNK(c
));
938 sprintf_append(NULL
, pps
, plen
, pbuflen
,
939 "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n",
942 (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c
)),
943 (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c
)),
944 talloc_reference_count(TC_PTR_FROM_CHUNK(c
)));
946 talloc_report_depth_str(TC_PTR_FROM_CHUNK(c
), pps
, plen
, pbuflen
, depth
+1);
949 tc
->flags
&= ~TALLOC_FLAG_LOOP
;
953 report on memory usage by all children of a pointer
955 char *talloc_describe_all(void)
961 if (null_context
== NULL
) {
965 sprintf_append(NULL
, &s
, &len
, &buflen
,
966 "full talloc report on '%s' (total %lu bytes in %lu blocks)\n",
967 talloc_get_name(null_context
),
968 (unsigned long)talloc_total_size(null_context
),
969 (unsigned long)talloc_total_blocks(null_context
));
974 talloc_report_depth_str(null_context
, &s
, &len
, &buflen
, 1);
980 enable leak reporting on exit
982 void talloc_enable_leak_report(void)
984 talloc_enable_null_tracking();
985 atexit(talloc_report_null
);
989 enable full leak reporting on exit
991 void talloc_enable_leak_report_full(void)
993 talloc_enable_null_tracking();
994 atexit(talloc_report_null_full
);
998 talloc and zero memory.
1000 void *_talloc_zero(const void *ctx
, size_t size
, const char *name
)
1002 void *p
= talloc_named_const(ctx
, size
, name
);
1005 memset(p
, '\0', size
);
1013 memdup with a talloc.
1015 void *_talloc_memdup(const void *t
, const void *p
, size_t size
, const char *name
)
1017 void *newp
= talloc_named_const(t
, size
, name
);
1020 memcpy(newp
, p
, size
);
1027 strdup with a talloc
1029 char *talloc_strdup(const void *t
, const char *p
)
1035 ret
= talloc_memdup(t
, p
, strlen(p
) + 1);
1037 talloc_set_name_const(ret
, ret
);
1043 append to a talloced string
1045 char *talloc_append_string(const void *t
, char *orig
, const char *append
)
1048 size_t olen
= strlen(orig
);
1054 alenz
= strlen(append
) + 1;
1056 ret
= talloc_realloc(t
, orig
, char, olen
+ alenz
);
1060 /* append the string with the trailing \0 */
1061 memcpy(&ret
[olen
], append
, alenz
);
1067 strndup with a talloc
1069 char *talloc_strndup(const void *t
, const char *p
, size_t n
)
1074 for (len
=0; len
<n
&& p
[len
]; len
++) ;
1076 ret
= _talloc(t
, len
+ 1);
1077 if (!ret
) { return NULL
; }
1078 memcpy(ret
, p
, len
);
1080 talloc_set_name_const(ret
, ret
);
1086 #define VA_COPY(dest, src) va_copy(dest, src)
1087 #elif defined(HAVE___VA_COPY)
1088 #define VA_COPY(dest, src) __va_copy(dest, src)
1090 #define VA_COPY(dest, src) (dest) = (src)
1094 char *talloc_vasprintf(const void *t
, const char *fmt
, va_list ap
)
1103 /* this call looks strange, but it makes it work on older solaris boxes */
1104 if ((len
= vsnprintf(&c
, 1, fmt
, ap2
)) < 0) {
1108 ret
= _talloc(t
, len
+1);
1111 vsnprintf(ret
, len
+1, fmt
, ap2
);
1112 talloc_set_name_const(ret
, ret
);
1120 Perform string formatting, and return a pointer to newly allocated
1121 memory holding the result, inside a memory pool.
1123 char *talloc_asprintf(const void *t
, const char *fmt
, ...)
1129 ret
= talloc_vasprintf(t
, fmt
, ap
);
1136 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1137 * and return @p s, which may have moved. Good for gradually
1138 * accumulating output into a string buffer.
1141 static char *talloc_vasprintf_append(char *s
, const char *fmt
, va_list ap
) PRINTF_ATTRIBUTE(2,0);
1143 static char *talloc_vasprintf_append(char *s
, const char *fmt
, va_list ap
)
1145 struct talloc_chunk
*tc
;
1150 return talloc_vasprintf(NULL
, fmt
, ap
);
1153 tc
= talloc_chunk_from_ptr(s
);
1157 s_len
= tc
->size
- 1;
1158 if ((len
= vsnprintf(NULL
, 0, fmt
, ap2
)) <= 0) {
1159 /* Either the vsnprintf failed or the format resulted in
1160 * no characters being formatted. In the former case, we
1161 * ought to return NULL, in the latter we ought to return
1162 * the original string. Most current callers of this
1163 * function expect it to never return NULL.
1168 s
= talloc_realloc(NULL
, s
, char, s_len
+ len
+1);
1169 if (!s
) return NULL
;
1173 vsnprintf(s
+s_len
, len
+1, fmt
, ap2
);
1174 talloc_set_name_const(s
, s
);
1180 Realloc @p s to append the formatted result of @p fmt and return @p
1181 s, which may have moved. Good for gradually accumulating output
1182 into a string buffer.
1184 char *talloc_asprintf_append(char *s
, const char *fmt
, ...)
1189 s
= talloc_vasprintf_append(s
, fmt
, ap
);
1195 alloc an array, checking for integer overflow in the array size
1197 void *_talloc_array(const void *ctx
, size_t el_size
, unsigned count
, const char *name
)
1199 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
1202 return talloc_named_const(ctx
, el_size
* count
, name
);
1206 alloc an zero array, checking for integer overflow in the array size
1208 void *_talloc_zero_array(const void *ctx
, size_t el_size
, unsigned count
, const char *name
)
1210 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
1213 return _talloc_zero(ctx
, el_size
* count
, name
);
1218 realloc an array, checking for integer overflow in the array size
1220 void *_talloc_realloc_array(const void *ctx
, void *ptr
, size_t el_size
, unsigned count
, const char *name
)
1222 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
1225 return _talloc_realloc(ctx
, ptr
, el_size
* count
, name
);
1229 a function version of talloc_realloc(), so it can be passed as a function pointer
1230 to libraries that want a realloc function (a realloc function encapsulates
1231 all the basic capabilities of an allocation library, which is why this is useful)
1233 void *talloc_realloc_fn(const void *context
, void *ptr
, size_t size
)
1235 return _talloc_realloc(context
, ptr
, size
, NULL
);
1239 static void talloc_autofree(void)
1241 talloc_free(cleanup_context
);
1242 cleanup_context
= NULL
;
1246 return a context which will be auto-freed on exit
1247 this is useful for reducing the noise in leak reports
1249 void *talloc_autofree_context(void)
1251 if (cleanup_context
== NULL
) {
1252 cleanup_context
= talloc_named_const(NULL
, 0, "autofree_context");
1253 atexit(talloc_autofree
);
1255 return cleanup_context
;
1258 size_t talloc_get_size(const void *context
)
1260 struct talloc_chunk
*tc
;
1262 if (context
== NULL
)
1265 tc
= talloc_chunk_from_ptr(context
);
1271 find a parent of this context that has the given name, if any
1273 void *talloc_find_parent_byname(const void *context
, const char *name
)
1275 struct talloc_chunk
*tc
;
1277 if (context
== NULL
) {
1281 tc
= talloc_chunk_from_ptr(context
);
1283 if (tc
->name
&& strcmp(tc
->name
, name
) == 0) {
1284 return TC_PTR_FROM_CHUNK(tc
);
1286 while (tc
&& tc
->prev
) tc
= tc
->prev
;
1296 show the parentage of a context
1298 void talloc_show_parents(const void *context
, FILE *file
)
1300 struct talloc_chunk
*tc
;
1302 if (context
== NULL
) {
1303 fprintf(file
, "talloc no parents for NULL\n");
1307 tc
= talloc_chunk_from_ptr(context
);
1308 fprintf(file
, "talloc parents of '%s'\n", talloc_get_name(context
));
1310 fprintf(file
, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc
)));
1311 while (tc
&& tc
->prev
) tc
= tc
->prev
;
1319 return 1 if ptr is a parent of context
1321 int talloc_is_parent(const void *context
, const char *ptr
)
1323 struct talloc_chunk
*tc
;
1325 if (context
== NULL
) {
1329 tc
= talloc_chunk_from_ptr(context
);
1331 if (TC_PTR_FROM_CHUNK(tc
) == ptr
) return 1;
1332 while (tc
&& tc
->prev
) tc
= tc
->prev
;