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
);
543 talloc_reference_destructor(tc
->refs
);
547 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
548 /* we have a free loop - stop looping */
552 if (tc
->destructor
) {
553 talloc_destructor_t d
= tc
->destructor
;
554 if (d
== (talloc_destructor_t
)-1) {
557 tc
->destructor
= (talloc_destructor_t
)-1;
562 tc
->destructor
= NULL
;
565 tc
->flags
|= TALLOC_FLAG_LOOP
;
567 talloc_free_children(ptr
);
570 _TLIST_REMOVE(tc
->parent
->child
, tc
);
571 if (tc
->parent
->child
) {
572 tc
->parent
->child
->parent
= tc
->parent
;
575 if (tc
->prev
) tc
->prev
->next
= tc
->next
;
576 if (tc
->next
) tc
->next
->prev
= tc
->prev
;
579 tc
->flags
|= TALLOC_FLAG_FREE
;
588 A talloc version of realloc. The context argument is only used if
591 void *_talloc_realloc(const void *context
, void *ptr
, size_t size
, const char *name
)
593 struct talloc_chunk
*tc
;
596 /* size zero is equivalent to free() */
602 if (size
>= MAX_TALLOC_SIZE
) {
606 /* realloc(NULL) is equavalent to malloc() */
608 return talloc_named_const(context
, size
, name
);
611 tc
= talloc_chunk_from_ptr(ptr
);
613 /* don't allow realloc on referenced pointers */
618 /* by resetting magic we catch users of the old memory */
619 tc
->flags
|= TALLOC_FLAG_FREE
;
622 new_ptr
= malloc(size
+ TC_HDR_SIZE
);
624 memcpy(new_ptr
, tc
, tc
->size
+ TC_HDR_SIZE
);
628 new_ptr
= realloc(tc
, size
+ TC_HDR_SIZE
);
631 tc
->flags
&= ~TALLOC_FLAG_FREE
;
636 tc
->flags
&= ~TALLOC_FLAG_FREE
;
638 tc
->parent
->child
= new_ptr
;
641 tc
->child
->parent
= new_ptr
;
652 talloc_set_name_const(TC_PTR_FROM_CHUNK(tc
), name
);
654 return TC_PTR_FROM_CHUNK(tc
);
658 move a lump of memory from one talloc context to another return the
659 ptr on success, or NULL if it could not be transferred.
660 passing NULL as ptr will always return NULL with no side effects.
662 void *talloc_steal(const void *new_ctx
, const void *ptr
)
664 struct talloc_chunk
*tc
, *new_tc
;
670 if (new_ctx
== NULL
) {
671 new_ctx
= null_context
;
674 tc
= talloc_chunk_from_ptr(ptr
);
676 if (new_ctx
== NULL
) {
678 _TLIST_REMOVE(tc
->parent
->child
, tc
);
679 if (tc
->parent
->child
) {
680 tc
->parent
->child
->parent
= tc
->parent
;
683 if (tc
->prev
) tc
->prev
->next
= tc
->next
;
684 if (tc
->next
) tc
->next
->prev
= tc
->prev
;
687 tc
->parent
= tc
->next
= tc
->prev
= NULL
;
688 return discard_const_p(void, ptr
);
691 new_tc
= talloc_chunk_from_ptr(new_ctx
);
694 return discard_const_p(void, ptr
);
698 _TLIST_REMOVE(tc
->parent
->child
, tc
);
699 if (tc
->parent
->child
) {
700 tc
->parent
->child
->parent
= tc
->parent
;
703 if (tc
->prev
) tc
->prev
->next
= tc
->next
;
704 if (tc
->next
) tc
->next
->prev
= tc
->prev
;
708 if (new_tc
->child
) new_tc
->child
->parent
= NULL
;
709 _TLIST_ADD(new_tc
->child
, tc
);
711 return discard_const_p(void, ptr
);
715 return the total size of a talloc pool (subtree)
717 off_t
talloc_total_size(const void *ptr
)
720 struct talloc_chunk
*c
, *tc
;
729 tc
= talloc_chunk_from_ptr(ptr
);
731 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
735 tc
->flags
|= TALLOC_FLAG_LOOP
;
738 for (c
=tc
->child
;c
;c
=c
->next
) {
739 total
+= talloc_total_size(TC_PTR_FROM_CHUNK(c
));
742 tc
->flags
&= ~TALLOC_FLAG_LOOP
;
748 return the total number of blocks in a talloc pool (subtree)
750 off_t
talloc_total_blocks(const void *ptr
)
753 struct talloc_chunk
*c
, *tc
= talloc_chunk_from_ptr(ptr
);
755 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
759 tc
->flags
|= TALLOC_FLAG_LOOP
;
762 for (c
=tc
->child
;c
;c
=c
->next
) {
763 total
+= talloc_total_blocks(TC_PTR_FROM_CHUNK(c
));
766 tc
->flags
&= ~TALLOC_FLAG_LOOP
;
772 return the number of external references to a pointer
774 static int talloc_reference_count(const void *ptr
)
776 struct talloc_chunk
*tc
= talloc_chunk_from_ptr(ptr
);
777 struct talloc_reference_handle
*h
;
780 for (h
=tc
->refs
;h
;h
=h
->next
) {
787 report on memory usage by all children of a pointer, giving a full tree view
789 void talloc_report_depth(const void *ptr
, FILE *f
, int depth
)
791 struct talloc_chunk
*c
, *tc
= talloc_chunk_from_ptr(ptr
);
793 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
797 tc
->flags
|= TALLOC_FLAG_LOOP
;
799 for (c
=tc
->child
;c
;c
=c
->next
) {
800 if (c
->name
== TALLOC_MAGIC_REFERENCE
) {
801 struct talloc_reference_handle
*handle
= TC_PTR_FROM_CHUNK(c
);
802 const char *name2
= talloc_get_name(handle
->ptr
);
803 fprintf(f
, "%*sreference to: %s\n", depth
*4, "", name2
);
805 const char *name
= talloc_get_name(TC_PTR_FROM_CHUNK(c
));
806 fprintf(f
, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n",
809 (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c
)),
810 (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c
)),
811 talloc_reference_count(TC_PTR_FROM_CHUNK(c
)));
812 talloc_report_depth(TC_PTR_FROM_CHUNK(c
), f
, depth
+1);
815 tc
->flags
&= ~TALLOC_FLAG_LOOP
;
819 report on memory usage by all children of a pointer, giving a full tree view
821 void talloc_report_full(const void *ptr
, FILE *f
)
826 if (ptr
== NULL
) return;
828 fprintf(f
,"full talloc report on '%s' (total %lu bytes in %lu blocks)\n",
829 talloc_get_name(ptr
),
830 (unsigned long)talloc_total_size(ptr
),
831 (unsigned long)talloc_total_blocks(ptr
));
833 talloc_report_depth(ptr
, f
, 1);
838 report on memory usage by all children of a pointer
840 void talloc_report(const void *ptr
, FILE *f
)
842 struct talloc_chunk
*c
, *tc
;
847 if (ptr
== NULL
) return;
849 fprintf(f
,"talloc report on '%s' (total %lu bytes in %lu blocks)\n",
850 talloc_get_name(ptr
),
851 (unsigned long)talloc_total_size(ptr
),
852 (unsigned long)talloc_total_blocks(ptr
));
854 tc
= talloc_chunk_from_ptr(ptr
);
856 for (c
=tc
->child
;c
;c
=c
->next
) {
857 fprintf(f
, "\t%-30s contains %6lu bytes in %3lu blocks\n",
858 talloc_get_name(TC_PTR_FROM_CHUNK(c
)),
859 (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c
)),
860 (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c
)));
866 report on any memory hanging off the null context
868 static void talloc_report_null(void)
870 if (talloc_total_size(null_context
) != 0) {
871 talloc_report(null_context
, stderr
);
876 report on any memory hanging off the null context
878 static void talloc_report_null_full(void)
880 if (talloc_total_size(null_context
) != 0) {
881 talloc_report_full(null_context
, stderr
);
886 enable tracking of the NULL context
888 void talloc_enable_null_tracking(void)
890 if (null_context
== NULL
) {
891 null_context
= talloc_named_const(NULL
, 0, "null_context");
896 /* Ugly calls to Samba-specific sprintf_append... JRA. */
899 report on memory usage by all children of a pointer, giving a full tree view
901 static void talloc_report_depth_str(const void *ptr
, char **pps
, ssize_t
*plen
, size_t *pbuflen
, int depth
)
903 struct talloc_chunk
*c
, *tc
= talloc_chunk_from_ptr(ptr
);
905 if (tc
->flags
& TALLOC_FLAG_LOOP
) {
909 tc
->flags
|= TALLOC_FLAG_LOOP
;
911 for (c
=tc
->child
;c
;c
=c
->next
) {
912 if (c
->name
== TALLOC_MAGIC_REFERENCE
) {
913 struct talloc_reference_handle
*handle
= TC_PTR_FROM_CHUNK(c
);
914 const char *name2
= talloc_get_name(handle
->ptr
);
916 sprintf_append(NULL
, pps
, plen
, pbuflen
,
917 "%*sreference to: %s\n", depth
*4, "", name2
);
920 const char *name
= talloc_get_name(TC_PTR_FROM_CHUNK(c
));
922 sprintf_append(NULL
, pps
, plen
, pbuflen
,
923 "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d)\n",
926 (unsigned long)talloc_total_size(TC_PTR_FROM_CHUNK(c
)),
927 (unsigned long)talloc_total_blocks(TC_PTR_FROM_CHUNK(c
)),
928 talloc_reference_count(TC_PTR_FROM_CHUNK(c
)));
930 talloc_report_depth_str(TC_PTR_FROM_CHUNK(c
), pps
, plen
, pbuflen
, depth
+1);
933 tc
->flags
&= ~TALLOC_FLAG_LOOP
;
937 report on memory usage by all children of a pointer
939 char *talloc_describe_all(void)
945 if (null_context
== NULL
) {
949 sprintf_append(NULL
, &s
, &len
, &buflen
,
950 "full talloc report on '%s' (total %lu bytes in %lu blocks)\n",
951 talloc_get_name(null_context
),
952 (unsigned long)talloc_total_size(null_context
),
953 (unsigned long)talloc_total_blocks(null_context
));
958 talloc_report_depth_str(null_context
, &s
, &len
, &buflen
, 1);
964 enable leak reporting on exit
966 void talloc_enable_leak_report(void)
968 talloc_enable_null_tracking();
969 atexit(talloc_report_null
);
973 enable full leak reporting on exit
975 void talloc_enable_leak_report_full(void)
977 talloc_enable_null_tracking();
978 atexit(talloc_report_null_full
);
982 talloc and zero memory.
984 void *_talloc_zero(const void *ctx
, size_t size
, const char *name
)
986 void *p
= talloc_named_const(ctx
, size
, name
);
989 memset(p
, '\0', size
);
997 memdup with a talloc.
999 void *_talloc_memdup(const void *t
, const void *p
, size_t size
, const char *name
)
1001 void *newp
= talloc_named_const(t
, size
, name
);
1004 memcpy(newp
, p
, size
);
1011 strdup with a talloc
1013 char *talloc_strdup(const void *t
, const char *p
)
1019 ret
= talloc_memdup(t
, p
, strlen(p
) + 1);
1021 talloc_set_name_const(ret
, ret
);
1027 append to a talloced string
1029 char *talloc_append_string(const void *t
, char *orig
, const char *append
)
1032 size_t olen
= strlen(orig
);
1038 alenz
= strlen(append
) + 1;
1040 ret
= talloc_realloc(t
, orig
, char, olen
+ alenz
);
1044 /* append the string with the trailing \0 */
1045 memcpy(&ret
[olen
], append
, alenz
);
1051 strndup with a talloc
1053 char *talloc_strndup(const void *t
, const char *p
, size_t n
)
1058 for (len
=0; len
<n
&& p
[len
]; len
++) ;
1060 ret
= _talloc(t
, len
+ 1);
1061 if (!ret
) { return NULL
; }
1062 memcpy(ret
, p
, len
);
1064 talloc_set_name_const(ret
, ret
);
1070 #define VA_COPY(dest, src) va_copy(dest, src)
1071 #elif defined(HAVE___VA_COPY)
1072 #define VA_COPY(dest, src) __va_copy(dest, src)
1074 #define VA_COPY(dest, src) (dest) = (src)
1078 char *talloc_vasprintf(const void *t
, const char *fmt
, va_list ap
)
1087 /* this call looks strange, but it makes it work on older solaris boxes */
1088 if ((len
= vsnprintf(&c
, 1, fmt
, ap2
)) < 0) {
1092 ret
= _talloc(t
, len
+1);
1095 vsnprintf(ret
, len
+1, fmt
, ap2
);
1096 talloc_set_name_const(ret
, ret
);
1104 Perform string formatting, and return a pointer to newly allocated
1105 memory holding the result, inside a memory pool.
1107 char *talloc_asprintf(const void *t
, const char *fmt
, ...)
1113 ret
= talloc_vasprintf(t
, fmt
, ap
);
1120 * Realloc @p s to append the formatted result of @p fmt and @p ap,
1121 * and return @p s, which may have moved. Good for gradually
1122 * accumulating output into a string buffer.
1125 static char *talloc_vasprintf_append(char *s
, const char *fmt
, va_list ap
) PRINTF_ATTRIBUTE(2,0);
1127 static char *talloc_vasprintf_append(char *s
, const char *fmt
, va_list ap
)
1129 struct talloc_chunk
*tc
;
1134 return talloc_vasprintf(NULL
, fmt
, ap
);
1137 tc
= talloc_chunk_from_ptr(s
);
1141 s_len
= tc
->size
- 1;
1142 if ((len
= vsnprintf(NULL
, 0, fmt
, ap2
)) <= 0) {
1143 /* Either the vsnprintf failed or the format resulted in
1144 * no characters being formatted. In the former case, we
1145 * ought to return NULL, in the latter we ought to return
1146 * the original string. Most current callers of this
1147 * function expect it to never return NULL.
1152 s
= talloc_realloc(NULL
, s
, char, s_len
+ len
+1);
1153 if (!s
) return NULL
;
1157 vsnprintf(s
+s_len
, len
+1, fmt
, ap2
);
1158 talloc_set_name_const(s
, s
);
1164 Realloc @p s to append the formatted result of @p fmt and return @p
1165 s, which may have moved. Good for gradually accumulating output
1166 into a string buffer.
1168 char *talloc_asprintf_append(char *s
, const char *fmt
, ...)
1173 s
= talloc_vasprintf_append(s
, fmt
, ap
);
1179 alloc an array, checking for integer overflow in the array size
1181 void *_talloc_array(const void *ctx
, size_t el_size
, unsigned count
, const char *name
)
1183 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
1186 return talloc_named_const(ctx
, el_size
* count
, name
);
1190 alloc an zero array, checking for integer overflow in the array size
1192 void *_talloc_zero_array(const void *ctx
, size_t el_size
, unsigned count
, const char *name
)
1194 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
1197 return _talloc_zero(ctx
, el_size
* count
, name
);
1202 realloc an array, checking for integer overflow in the array size
1204 void *_talloc_realloc_array(const void *ctx
, void *ptr
, size_t el_size
, unsigned count
, const char *name
)
1206 if (count
>= MAX_TALLOC_SIZE
/el_size
) {
1209 return _talloc_realloc(ctx
, ptr
, el_size
* count
, name
);
1213 a function version of talloc_realloc(), so it can be passed as a function pointer
1214 to libraries that want a realloc function (a realloc function encapsulates
1215 all the basic capabilities of an allocation library, which is why this is useful)
1217 void *talloc_realloc_fn(const void *context
, void *ptr
, size_t size
)
1219 return _talloc_realloc(context
, ptr
, size
, NULL
);
1223 static void talloc_autofree(void)
1225 talloc_free(cleanup_context
);
1226 cleanup_context
= NULL
;
1230 return a context which will be auto-freed on exit
1231 this is useful for reducing the noise in leak reports
1233 void *talloc_autofree_context(void)
1235 if (cleanup_context
== NULL
) {
1236 cleanup_context
= talloc_named_const(NULL
, 0, "autofree_context");
1237 atexit(talloc_autofree
);
1239 return cleanup_context
;
1242 size_t talloc_get_size(const void *context
)
1244 struct talloc_chunk
*tc
;
1246 if (context
== NULL
)
1249 tc
= talloc_chunk_from_ptr(context
);
1255 find a parent of this context that has the given name, if any
1257 void *talloc_find_parent_byname(const void *context
, const char *name
)
1259 struct talloc_chunk
*tc
;
1261 if (context
== NULL
) {
1265 tc
= talloc_chunk_from_ptr(context
);
1267 if (tc
->name
&& strcmp(tc
->name
, name
) == 0) {
1268 return TC_PTR_FROM_CHUNK(tc
);
1270 while (tc
&& tc
->prev
) tc
= tc
->prev
;
1277 show the parentage of a context
1279 void talloc_show_parents(const void *context
, FILE *file
)
1281 struct talloc_chunk
*tc
;
1283 if (context
== NULL
) {
1284 fprintf(file
, "talloc no parents for NULL\n");
1288 tc
= talloc_chunk_from_ptr(context
);
1289 fprintf(file
, "talloc parents of '%s'\n", talloc_get_name(context
));
1291 fprintf(file
, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc
)));
1292 while (tc
&& tc
->prev
) tc
= tc
->prev
;