talloc: change TALLOC_MAGIC for version 2.0.0
[metze/samba/wip.git] / lib / talloc / talloc.c
1 /* 
2    Samba Unix SMB/CIFS implementation.
3
4    Samba trivial allocation library - new interface
5
6    NOTE: Please read talloc_guide.txt for full documentation
7
8    Copyright (C) Andrew Tridgell 2004
9    Copyright (C) Stefan Metzmacher 2006
10    
11      ** NOTE! The following LGPL license applies to the talloc
12      ** library. This does NOT imply that all of Samba is released
13      ** under the LGPL
14    
15    This library is free software; you can redistribute it and/or
16    modify it under the terms of the GNU Lesser General Public
17    License as published by the Free Software Foundation; either
18    version 3 of the License, or (at your option) any later version.
19
20    This library is distributed in the hope that it will be useful,
21    but WITHOUT ANY WARRANTY; without even the implied warranty of
22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23    Lesser General Public License for more details.
24
25    You should have received a copy of the GNU Lesser General Public
26    License along with this library; if not, see <http://www.gnu.org/licenses/>.
27 */
28
29 /*
30   inspired by http://swapped.cc/halloc/
31 */
32
33 #ifdef _SAMBA_BUILD_
34 #include "version.h"
35 #if (SAMBA_VERSION_MAJOR<4)
36 #include "includes.h"
37 /* This is to circumvent SAMBA3's paranoid malloc checker. Here in this file
38  * we trust ourselves... */
39 #ifdef malloc
40 #undef malloc
41 #endif
42 #ifdef realloc
43 #undef realloc
44 #endif
45 #define _TALLOC_SAMBA3
46 #endif /* (SAMBA_VERSION_MAJOR<4) */
47 #endif /* _SAMBA_BUILD_ */
48
49 #ifndef _TALLOC_SAMBA3
50 #include "replace.h"
51 #include "talloc.h"
52 #endif /* not _TALLOC_SAMBA3 */
53
54 /* use this to force every realloc to change the pointer, to stress test
55    code that might not cope */
56 #define ALWAYS_REALLOC 0
57
58
59 #define MAX_TALLOC_SIZE 0x10000000
60 #define TALLOC_MAGIC_V1 0xe814ec70
61 #define TALLOC_MAGIC_V2 0xe814ec80
62 #define TALLOC_MAGIC    TALLOC_MAGIC_V2
63 #define TALLOC_FLAG_FREE 0x01
64 #define TALLOC_FLAG_LOOP 0x02
65 #define TALLOC_FLAG_POOL 0x04           /* This is a talloc pool */
66 #define TALLOC_FLAG_POOLMEM 0x08        /* This is allocated in a pool */
67 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
68
69 /* by default we abort when given a bad pointer (such as when talloc_free() is called 
70    on a pointer that came from malloc() */
71 #ifndef TALLOC_ABORT
72 #define TALLOC_ABORT(reason) abort()
73 #endif
74
75 #ifndef discard_const_p
76 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
77 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
78 #else
79 # define discard_const_p(type, ptr) ((type *)(ptr))
80 #endif
81 #endif
82
83 /* these macros gain us a few percent of speed on gcc */
84 #if (__GNUC__ >= 3)
85 /* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
86    as its first argument */
87 #ifndef likely
88 #define likely(x)   __builtin_expect(!!(x), 1)
89 #endif
90 #ifndef unlikely
91 #define unlikely(x) __builtin_expect(!!(x), 0)
92 #endif
93 #else
94 #ifndef likely
95 #define likely(x) (x)
96 #endif
97 #ifndef unlikely
98 #define unlikely(x) (x)
99 #endif
100 #endif
101
102 /* this null_context is only used if talloc_enable_leak_report() or
103    talloc_enable_leak_report_full() is called, otherwise it remains
104    NULL
105 */
106 static void *null_context;
107 static void *autofree_context;
108
109 struct talloc_reference_handle {
110         struct talloc_reference_handle *next, *prev;
111         void *ptr;
112 };
113
114 typedef int (*talloc_destructor_t)(void *);
115
116 struct talloc_chunk {
117         struct talloc_chunk *next, *prev;
118         struct talloc_chunk *parent, *child;
119         struct talloc_reference_handle *refs;
120         talloc_destructor_t destructor;
121         const char *name;
122         size_t size;
123         unsigned flags;
124
125         /*
126          * "pool" has dual use:
127          *
128          * For the talloc pool itself (i.e. TALLOC_FLAG_POOL is set), "pool"
129          * marks the end of the currently allocated area.
130          *
131          * For members of the pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool"
132          * is a pointer to the struct talloc_chunk of the pool that it was
133          * allocated from. This way children can quickly find the pool to chew
134          * from.
135          */
136         void *pool;
137 };
138
139 /* 16 byte alignment seems to keep everyone happy */
140 #define TC_HDR_SIZE ((sizeof(struct talloc_chunk)+15)&~15)
141 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
142
143 static void (*talloc_abort_fn)(const char *reason);
144
145 void talloc_set_abort_fn(void (*abort_fn)(const char *reason))
146 {
147         talloc_abort_fn = abort_fn;
148 }
149
150 static void talloc_abort(const char *reason)
151 {
152         if (!talloc_abort_fn) {
153                 TALLOC_ABORT(reason);
154         }
155
156         talloc_abort_fn(reason);
157 }
158
159 static void talloc_abort_magic_v1(void)
160 {
161         talloc_abort("Bad talloc magic value - old magic v1 used");
162 }
163
164 static void talloc_abort_double_free(void)
165 {
166         talloc_abort("Bad talloc magic value - double free");
167 }
168
169 static void talloc_abort_unknown_value(void)
170 {
171         talloc_abort("Bad talloc magic value - unknown value");
172 }
173
174 /* panic if we get a bad magic value */
175 static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
176 {
177         const char *pp = (const char *)ptr;
178         struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
179         if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) { 
180                 if ((tc->flags & (~0xF)) == TALLOC_MAGIC_V1)) {
181                         talloc_abort_magic_v1();
182                 }
183
184                 if (tc->flags & TALLOC_FLAG_FREE) {
185                         talloc_abort_double_free();
186                 } else {
187                         talloc_abort_unknown_value();
188                 }
189         }
190         return tc;
191 }
192
193 /* hook into the front of the list */
194 #define _TLIST_ADD(list, p) \
195 do { \
196         if (!(list)) { \
197                 (list) = (p); \
198                 (p)->next = (p)->prev = NULL; \
199         } else { \
200                 (list)->prev = (p); \
201                 (p)->next = (list); \
202                 (p)->prev = NULL; \
203                 (list) = (p); \
204         }\
205 } while (0)
206
207 /* remove an element from a list - element doesn't have to be in list. */
208 #define _TLIST_REMOVE(list, p) \
209 do { \
210         if ((p) == (list)) { \
211                 (list) = (p)->next; \
212                 if (list) (list)->prev = NULL; \
213         } else { \
214                 if ((p)->prev) (p)->prev->next = (p)->next; \
215                 if ((p)->next) (p)->next->prev = (p)->prev; \
216         } \
217         if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
218 } while (0)
219
220
221 /*
222   return the parent chunk of a pointer
223 */
224 static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr)
225 {
226         struct talloc_chunk *tc;
227
228         if (unlikely(ptr == NULL)) {
229                 return NULL;
230         }
231
232         tc = talloc_chunk_from_ptr(ptr);
233         while (tc->prev) tc=tc->prev;
234
235         return tc->parent;
236 }
237
238 void *talloc_parent(const void *ptr)
239 {
240         struct talloc_chunk *tc = talloc_parent_chunk(ptr);
241         return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
242 }
243
244 /*
245   find parents name
246 */
247 const char *talloc_parent_name(const void *ptr)
248 {
249         struct talloc_chunk *tc = talloc_parent_chunk(ptr);
250         return tc? tc->name : NULL;
251 }
252
253 /*
254   A pool carries an in-pool object count count in the first 16 bytes.
255   bytes. This is done to support talloc_steal() to a parent outside of the
256   pool. The count includes the pool itself, so a talloc_free() on a pool will
257   only destroy the pool if the count has dropped to zero. A talloc_free() of a
258   pool member will reduce the count, and eventually also call free(3) on the
259   pool memory.
260
261   The object count is not put into "struct talloc_chunk" because it is only
262   relevant for talloc pools and the alignment to 16 bytes would increase the
263   memory footprint of each talloc chunk by those 16 bytes.
264 */
265
266 #define TALLOC_POOL_HDR_SIZE 16
267
268 static unsigned int *talloc_pool_objectcount(struct talloc_chunk *tc)
269 {
270         return (unsigned int *)((char *)tc + sizeof(struct talloc_chunk));
271 }
272
273 /*
274   Allocate from a pool
275 */
276
277 static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,
278                                               size_t size)
279 {
280         struct talloc_chunk *pool_ctx = NULL;
281         size_t space_left;
282         struct talloc_chunk *result;
283         size_t chunk_size;
284
285         if (parent == NULL) {
286                 return NULL;
287         }
288
289         if (parent->flags & TALLOC_FLAG_POOL) {
290                 pool_ctx = parent;
291         }
292         else if (parent->flags & TALLOC_FLAG_POOLMEM) {
293                 pool_ctx = (struct talloc_chunk *)parent->pool;
294         }
295
296         if (pool_ctx == NULL) {
297                 return NULL;
298         }
299
300         space_left = ((char *)pool_ctx + TC_HDR_SIZE + pool_ctx->size)
301                 - ((char *)pool_ctx->pool);
302
303         /*
304          * Align size to 16 bytes
305          */
306         chunk_size = ((size + 15) & ~15);
307
308         if (space_left < chunk_size) {
309                 return NULL;
310         }
311
312         result = (struct talloc_chunk *)pool_ctx->pool;
313
314 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
315         VALGRIND_MAKE_MEM_UNDEFINED(result, size);
316 #endif
317
318         pool_ctx->pool = (void *)((char *)result + chunk_size);
319
320         result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM;
321         result->pool = pool_ctx;
322
323         *talloc_pool_objectcount(pool_ctx) += 1;
324
325         return result;
326 }
327
328 /* 
329    Allocate a bit of memory as a child of an existing pointer
330 */
331 static inline void *__talloc(const void *context, size_t size)
332 {
333         struct talloc_chunk *tc = NULL;
334
335         if (unlikely(context == NULL)) {
336                 context = null_context;
337         }
338
339         if (unlikely(size >= MAX_TALLOC_SIZE)) {
340                 return NULL;
341         }
342
343         if (context != NULL) {
344                 tc = talloc_alloc_pool(talloc_chunk_from_ptr(context),
345                                        TC_HDR_SIZE+size);
346         }
347
348         if (tc == NULL) {
349                 tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size);
350                 if (unlikely(tc == NULL)) return NULL;
351                 tc->flags = TALLOC_MAGIC;
352                 tc->pool  = NULL;
353         }
354
355         tc->size = size;
356         tc->destructor = NULL;
357         tc->child = NULL;
358         tc->name = NULL;
359         tc->refs = NULL;
360
361         if (likely(context)) {
362                 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
363
364                 if (parent->child) {
365                         parent->child->parent = NULL;
366                         tc->next = parent->child;
367                         tc->next->prev = tc;
368                 } else {
369                         tc->next = NULL;
370                 }
371                 tc->parent = parent;
372                 tc->prev = NULL;
373                 parent->child = tc;
374         } else {
375                 tc->next = tc->prev = tc->parent = NULL;
376         }
377
378         return TC_PTR_FROM_CHUNK(tc);
379 }
380
381 /*
382  * Create a talloc pool
383  */
384
385 void *talloc_pool(const void *context, size_t size)
386 {
387         void *result = __talloc(context, size + TALLOC_POOL_HDR_SIZE);
388         struct talloc_chunk *tc;
389
390         if (unlikely(result == NULL)) {
391                 return NULL;
392         }
393
394         tc = talloc_chunk_from_ptr(result);
395
396         tc->flags |= TALLOC_FLAG_POOL;
397         tc->pool = (char *)result + TALLOC_POOL_HDR_SIZE;
398
399         *talloc_pool_objectcount(tc) = 1;
400
401 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
402         VALGRIND_MAKE_MEM_NOACCESS(tc->pool, size);
403 #endif
404
405         return result;
406 }
407
408 /*
409   setup a destructor to be called on free of a pointer
410   the destructor should return 0 on success, or -1 on failure.
411   if the destructor fails then the free is failed, and the memory can
412   be continued to be used
413 */
414 void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
415 {
416         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
417         tc->destructor = destructor;
418 }
419
420 /*
421   increase the reference count on a piece of memory. 
422 */
423 int talloc_increase_ref_count(const void *ptr)
424 {
425         if (unlikely(!talloc_reference(null_context, ptr))) {
426                 return -1;
427         }
428         return 0;
429 }
430
431 /*
432   helper for talloc_reference()
433
434   this is referenced by a function pointer and should not be inline
435 */
436 static int talloc_reference_destructor(struct talloc_reference_handle *handle)
437 {
438         struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
439         _TLIST_REMOVE(ptr_tc->refs, handle);
440         return 0;
441 }
442
443 /*
444    more efficient way to add a name to a pointer - the name must point to a 
445    true string constant
446 */
447 static inline void _talloc_set_name_const(const void *ptr, const char *name)
448 {
449         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
450         tc->name = name;
451 }
452
453 /*
454   internal talloc_named_const()
455 */
456 static inline void *_talloc_named_const(const void *context, size_t size, const char *name)
457 {
458         void *ptr;
459
460         ptr = __talloc(context, size);
461         if (unlikely(ptr == NULL)) {
462                 return NULL;
463         }
464
465         _talloc_set_name_const(ptr, name);
466
467         return ptr;
468 }
469
470 /*
471   make a secondary reference to a pointer, hanging off the given context.
472   the pointer remains valid until both the original caller and this given
473   context are freed.
474   
475   the major use for this is when two different structures need to reference the 
476   same underlying data, and you want to be able to free the two instances separately,
477   and in either order
478 */
479 void *_talloc_reference(const void *context, const void *ptr)
480 {
481         struct talloc_chunk *tc;
482         struct talloc_reference_handle *handle;
483         if (unlikely(ptr == NULL)) return NULL;
484
485         tc = talloc_chunk_from_ptr(ptr);
486         handle = (struct talloc_reference_handle *)_talloc_named_const(context,
487                                                    sizeof(struct talloc_reference_handle),
488                                                    TALLOC_MAGIC_REFERENCE);
489         if (unlikely(handle == NULL)) return NULL;
490
491         /* note that we hang the destructor off the handle, not the
492            main context as that allows the caller to still setup their
493            own destructor on the context if they want to */
494         talloc_set_destructor(handle, talloc_reference_destructor);
495         handle->ptr = discard_const_p(void, ptr);
496         _TLIST_ADD(tc->refs, handle);
497         return handle->ptr;
498 }
499
500
501 /* 
502    internal talloc_free call
503 */
504 static inline int _talloc_free(void *ptr)
505 {
506         struct talloc_chunk *tc;
507
508         if (unlikely(ptr == NULL)) {
509                 return -1;
510         }
511
512         tc = talloc_chunk_from_ptr(ptr);
513
514         if (unlikely(tc->refs)) {
515                 int is_child;
516                 /* check this is a reference from a child or grantchild
517                  * back to it's parent or grantparent
518                  *
519                  * in that case we need to remove the reference and
520                  * call another instance of talloc_free() on the current
521                  * pointer.
522                  */
523                 is_child = talloc_is_parent(tc->refs, ptr);
524                 _talloc_free(tc->refs);
525                 if (is_child) {
526                         return _talloc_free(ptr);
527                 }
528                 return -1;
529         }
530
531         if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) {
532                 /* we have a free loop - stop looping */
533                 return 0;
534         }
535
536         if (unlikely(tc->destructor)) {
537                 talloc_destructor_t d = tc->destructor;
538                 if (d == (talloc_destructor_t)-1) {
539                         return -1;
540                 }
541                 tc->destructor = (talloc_destructor_t)-1;
542                 if (d(ptr) == -1) {
543                         tc->destructor = d;
544                         return -1;
545                 }
546                 tc->destructor = NULL;
547         }
548
549         if (tc->parent) {
550                 _TLIST_REMOVE(tc->parent->child, tc);
551                 if (tc->parent->child) {
552                         tc->parent->child->parent = tc->parent;
553                 }
554         } else {
555                 if (tc->prev) tc->prev->next = tc->next;
556                 if (tc->next) tc->next->prev = tc->prev;
557         }
558
559         tc->flags |= TALLOC_FLAG_LOOP;
560
561         while (tc->child) {
562                 /* we need to work out who will own an abandoned child
563                    if it cannot be freed. In priority order, the first
564                    choice is owner of any remaining reference to this
565                    pointer, the second choice is our parent, and the
566                    final choice is the null context. */
567                 void *child = TC_PTR_FROM_CHUNK(tc->child);
568                 const void *new_parent = null_context;
569                 if (unlikely(tc->child->refs)) {
570                         struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
571                         if (p) new_parent = TC_PTR_FROM_CHUNK(p);
572                 }
573                 if (unlikely(_talloc_free(child) == -1)) {
574                         if (new_parent == null_context) {
575                                 struct talloc_chunk *p = talloc_parent_chunk(ptr);
576                                 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
577                         }
578                         talloc_steal(new_parent, child);
579                 }
580         }
581
582         tc->flags |= TALLOC_FLAG_FREE;
583
584         if (tc->flags & (TALLOC_FLAG_POOL|TALLOC_FLAG_POOLMEM)) {
585                 struct talloc_chunk *pool;
586                 unsigned int *pool_object_count;
587
588                 pool = (tc->flags & TALLOC_FLAG_POOL)
589                         ? tc : (struct talloc_chunk *)tc->pool;
590
591                 pool_object_count = talloc_pool_objectcount(pool);
592
593                 if (*pool_object_count == 0) {
594                         talloc_abort("Pool object count zero!");
595                 }
596
597                 *pool_object_count -= 1;
598
599                 if (*pool_object_count == 0) {
600                         free(pool);
601                 }
602         }
603         else {
604                 free(tc);
605         }
606         return 0;
607 }
608
609 /* 
610    move a lump of memory from one talloc context to another return the
611    ptr on success, or NULL if it could not be transferred.
612    passing NULL as ptr will always return NULL with no side effects.
613 */
614 void *_talloc_steal(const void *new_ctx, const void *ptr)
615 {
616         struct talloc_chunk *tc, *new_tc;
617
618         if (unlikely(!ptr)) {
619                 return NULL;
620         }
621
622         if (unlikely(new_ctx == NULL)) {
623                 new_ctx = null_context;
624         }
625
626         tc = talloc_chunk_from_ptr(ptr);
627
628         if (unlikely(new_ctx == NULL)) {
629                 if (tc->parent) {
630                         _TLIST_REMOVE(tc->parent->child, tc);
631                         if (tc->parent->child) {
632                                 tc->parent->child->parent = tc->parent;
633                         }
634                 } else {
635                         if (tc->prev) tc->prev->next = tc->next;
636                         if (tc->next) tc->next->prev = tc->prev;
637                 }
638                 
639                 tc->parent = tc->next = tc->prev = NULL;
640                 return discard_const_p(void, ptr);
641         }
642
643         new_tc = talloc_chunk_from_ptr(new_ctx);
644
645         if (unlikely(tc == new_tc || tc->parent == new_tc)) {
646                 return discard_const_p(void, ptr);
647         }
648
649         if (tc->parent) {
650                 _TLIST_REMOVE(tc->parent->child, tc);
651                 if (tc->parent->child) {
652                         tc->parent->child->parent = tc->parent;
653                 }
654         } else {
655                 if (tc->prev) tc->prev->next = tc->next;
656                 if (tc->next) tc->next->prev = tc->prev;
657         }
658
659         tc->parent = new_tc;
660         if (new_tc->child) new_tc->child->parent = NULL;
661         _TLIST_ADD(new_tc->child, tc);
662
663         return discard_const_p(void, ptr);
664 }
665
666
667
668 /*
669   remove a secondary reference to a pointer. This undo's what
670   talloc_reference() has done. The context and pointer arguments
671   must match those given to a talloc_reference()
672 */
673 static inline int talloc_unreference(const void *context, const void *ptr)
674 {
675         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
676         struct talloc_reference_handle *h;
677
678         if (unlikely(context == NULL)) {
679                 context = null_context;
680         }
681
682         for (h=tc->refs;h;h=h->next) {
683                 struct talloc_chunk *p = talloc_parent_chunk(h);
684                 if (p == NULL) {
685                         if (context == NULL) break;
686                 } else if (TC_PTR_FROM_CHUNK(p) == context) {
687                         break;
688                 }
689         }
690         if (h == NULL) {
691                 return -1;
692         }
693
694         return _talloc_free(h);
695 }
696
697 /*
698   remove a specific parent context from a pointer. This is a more
699   controlled varient of talloc_free()
700 */
701 int talloc_unlink(const void *context, void *ptr)
702 {
703         struct talloc_chunk *tc_p, *new_p;
704         void *new_parent;
705
706         if (ptr == NULL) {
707                 return -1;
708         }
709
710         if (context == NULL) {
711                 context = null_context;
712         }
713
714         if (talloc_unreference(context, ptr) == 0) {
715                 return 0;
716         }
717
718         if (context == NULL) {
719                 if (talloc_parent_chunk(ptr) != NULL) {
720                         return -1;
721                 }
722         } else {
723                 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
724                         return -1;
725                 }
726         }
727         
728         tc_p = talloc_chunk_from_ptr(ptr);
729
730         if (tc_p->refs == NULL) {
731                 return _talloc_free(ptr);
732         }
733
734         new_p = talloc_parent_chunk(tc_p->refs);
735         if (new_p) {
736                 new_parent = TC_PTR_FROM_CHUNK(new_p);
737         } else {
738                 new_parent = NULL;
739         }
740
741         if (talloc_unreference(new_parent, ptr) != 0) {
742                 return -1;
743         }
744
745         talloc_steal(new_parent, ptr);
746
747         return 0;
748 }
749
750 /*
751   add a name to an existing pointer - va_list version
752 */
753 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
754
755 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
756 {
757         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
758         tc->name = talloc_vasprintf(ptr, fmt, ap);
759         if (likely(tc->name)) {
760                 _talloc_set_name_const(tc->name, ".name");
761         }
762         return tc->name;
763 }
764
765 /*
766   add a name to an existing pointer
767 */
768 const char *talloc_set_name(const void *ptr, const char *fmt, ...)
769 {
770         const char *name;
771         va_list ap;
772         va_start(ap, fmt);
773         name = talloc_set_name_v(ptr, fmt, ap);
774         va_end(ap);
775         return name;
776 }
777
778
779 /*
780   create a named talloc pointer. Any talloc pointer can be named, and
781   talloc_named() operates just like talloc() except that it allows you
782   to name the pointer.
783 */
784 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
785 {
786         va_list ap;
787         void *ptr;
788         const char *name;
789
790         ptr = __talloc(context, size);
791         if (unlikely(ptr == NULL)) return NULL;
792
793         va_start(ap, fmt);
794         name = talloc_set_name_v(ptr, fmt, ap);
795         va_end(ap);
796
797         if (unlikely(name == NULL)) {
798                 _talloc_free(ptr);
799                 return NULL;
800         }
801
802         return ptr;
803 }
804
805 /*
806   return the name of a talloc ptr, or "UNNAMED"
807 */
808 const char *talloc_get_name(const void *ptr)
809 {
810         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
811         if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
812                 return ".reference";
813         }
814         if (likely(tc->name)) {
815                 return tc->name;
816         }
817         return "UNNAMED";
818 }
819
820
821 /*
822   check if a pointer has the given name. If it does, return the pointer,
823   otherwise return NULL
824 */
825 void *talloc_check_name(const void *ptr, const char *name)
826 {
827         const char *pname;
828         if (unlikely(ptr == NULL)) return NULL;
829         pname = talloc_get_name(ptr);
830         if (likely(pname == name || strcmp(pname, name) == 0)) {
831                 return discard_const_p(void, ptr);
832         }
833         return NULL;
834 }
835
836 static void talloc_abort_type_missmatch(const char *location,
837                                         const char *name,
838                                         const char *expected)
839 {
840         const char *reason;
841
842         reason = talloc_asprintf(NULL,
843                                  "%s: Type mismatch: name[%s] expected[%s]",
844                                  location,
845                                  name?name:"NULL",
846                                  expected);
847         if (!reason) {
848                 reason = "Type mismatch";
849         }
850
851         talloc_abort(reason);
852 }
853
854 void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location)
855 {
856         const char *pname;
857
858         if (unlikely(ptr == NULL)) {
859                 talloc_abort_type_missmatch(location, NULL, name);
860                 return NULL;
861         }
862
863         pname = talloc_get_name(ptr);
864         if (likely(pname == name || strcmp(pname, name) == 0)) {
865                 return discard_const_p(void, ptr);
866         }
867
868         talloc_abort_type_missmatch(location, pname, name);
869         return NULL;
870 }
871
872 /*
873   this is for compatibility with older versions of talloc
874 */
875 void *talloc_init(const char *fmt, ...)
876 {
877         va_list ap;
878         void *ptr;
879         const char *name;
880
881         /*
882          * samba3 expects talloc_report_depth_cb(NULL, ...)
883          * reports all talloc'ed memory, so we need to enable
884          * null_tracking
885          */
886         talloc_enable_null_tracking();
887
888         ptr = __talloc(NULL, 0);
889         if (unlikely(ptr == NULL)) return NULL;
890
891         va_start(ap, fmt);
892         name = talloc_set_name_v(ptr, fmt, ap);
893         va_end(ap);
894
895         if (unlikely(name == NULL)) {
896                 _talloc_free(ptr);
897                 return NULL;
898         }
899
900         return ptr;
901 }
902
903 /*
904   this is a replacement for the Samba3 talloc_destroy_pool functionality. It
905   should probably not be used in new code. It's in here to keep the talloc
906   code consistent across Samba 3 and 4.
907 */
908 void talloc_free_children(void *ptr)
909 {
910         struct talloc_chunk *tc;
911
912         if (unlikely(ptr == NULL)) {
913                 return;
914         }
915
916         tc = talloc_chunk_from_ptr(ptr);
917
918         while (tc->child) {
919                 /* we need to work out who will own an abandoned child
920                    if it cannot be freed. In priority order, the first
921                    choice is owner of any remaining reference to this
922                    pointer, the second choice is our parent, and the
923                    final choice is the null context. */
924                 void *child = TC_PTR_FROM_CHUNK(tc->child);
925                 const void *new_parent = null_context;
926                 if (unlikely(tc->child->refs)) {
927                         struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
928                         if (p) new_parent = TC_PTR_FROM_CHUNK(p);
929                 }
930                 if (unlikely(_talloc_free(child) == -1)) {
931                         if (new_parent == null_context) {
932                                 struct talloc_chunk *p = talloc_parent_chunk(ptr);
933                                 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
934                         }
935                         talloc_steal(new_parent, child);
936                 }
937         }
938
939         if ((tc->flags & TALLOC_FLAG_POOL)
940             && (*talloc_pool_objectcount(tc) == 1)) {
941                 tc->pool = ((char *)tc + TC_HDR_SIZE + TALLOC_POOL_HDR_SIZE);
942 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
943                 VALGRIND_MAKE_MEM_NOACCESS(
944                         tc->pool, tc->size - TALLOC_POOL_HDR_SIZE);
945 #endif
946         }
947 }
948
949 /* 
950    Allocate a bit of memory as a child of an existing pointer
951 */
952 void *_talloc(const void *context, size_t size)
953 {
954         return __talloc(context, size);
955 }
956
957 /*
958   externally callable talloc_set_name_const()
959 */
960 void talloc_set_name_const(const void *ptr, const char *name)
961 {
962         _talloc_set_name_const(ptr, name);
963 }
964
965 /*
966   create a named talloc pointer. Any talloc pointer can be named, and
967   talloc_named() operates just like talloc() except that it allows you
968   to name the pointer.
969 */
970 void *talloc_named_const(const void *context, size_t size, const char *name)
971 {
972         return _talloc_named_const(context, size, name);
973 }
974
975 /* 
976    free a talloc pointer. This also frees all child pointers of this 
977    pointer recursively
978
979    return 0 if the memory is actually freed, otherwise -1. The memory
980    will not be freed if the ref_count is > 1 or the destructor (if
981    any) returns non-zero
982 */
983 int talloc_free(void *ptr)
984 {
985         return _talloc_free(ptr);
986 }
987
988
989
990 /*
991   A talloc version of realloc. The context argument is only used if
992   ptr is NULL
993 */
994 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
995 {
996         struct talloc_chunk *tc;
997         void *new_ptr;
998         bool malloced = false;
999
1000         /* size zero is equivalent to free() */
1001         if (unlikely(size == 0)) {
1002                 _talloc_free(ptr);
1003                 return NULL;
1004         }
1005
1006         if (unlikely(size >= MAX_TALLOC_SIZE)) {
1007                 return NULL;
1008         }
1009
1010         /* realloc(NULL) is equivalent to malloc() */
1011         if (ptr == NULL) {
1012                 return _talloc_named_const(context, size, name);
1013         }
1014
1015         tc = talloc_chunk_from_ptr(ptr);
1016
1017         /* don't allow realloc on referenced pointers */
1018         if (unlikely(tc->refs)) {
1019                 return NULL;
1020         }
1021
1022         /* don't let anybody try to realloc a talloc_pool */
1023         if (unlikely(tc->flags & TALLOC_FLAG_POOL)) {
1024                 return NULL;
1025         }
1026
1027         /* don't shrink if we have less than 1k to gain */
1028         if ((size < tc->size) && ((tc->size - size) < 1024)) {
1029                 tc->size = size;
1030                 return ptr;
1031         }
1032
1033         /* by resetting magic we catch users of the old memory */
1034         tc->flags |= TALLOC_FLAG_FREE;
1035
1036 #if ALWAYS_REALLOC
1037         new_ptr = malloc(size + TC_HDR_SIZE);
1038         if (new_ptr) {
1039                 memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
1040                 free(tc);
1041         }
1042 #else
1043         if (tc->flags & TALLOC_FLAG_POOLMEM) {
1044
1045                 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE);
1046                 *talloc_pool_objectcount((struct talloc_chunk *)
1047                                          (tc->pool)) -= 1;
1048
1049                 if (new_ptr == NULL) {
1050                         new_ptr = malloc(TC_HDR_SIZE+size);
1051                         malloced = true;
1052                 }
1053
1054                 if (new_ptr) {
1055                         memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
1056                 }
1057         }
1058         else {
1059                 new_ptr = realloc(tc, size + TC_HDR_SIZE);
1060         }
1061 #endif
1062         if (unlikely(!new_ptr)) {       
1063                 tc->flags &= ~TALLOC_FLAG_FREE; 
1064                 return NULL; 
1065         }
1066
1067         tc = (struct talloc_chunk *)new_ptr;
1068         tc->flags &= ~TALLOC_FLAG_FREE;
1069         if (malloced) {
1070                 tc->flags &= ~TALLOC_FLAG_POOLMEM;
1071         }
1072         if (tc->parent) {
1073                 tc->parent->child = tc;
1074         }
1075         if (tc->child) {
1076                 tc->child->parent = tc;
1077         }
1078
1079         if (tc->prev) {
1080                 tc->prev->next = tc;
1081         }
1082         if (tc->next) {
1083                 tc->next->prev = tc;
1084         }
1085
1086         tc->size = size;
1087         _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
1088
1089         return TC_PTR_FROM_CHUNK(tc);
1090 }
1091
1092 /*
1093   a wrapper around talloc_steal() for situations where you are moving a pointer
1094   between two structures, and want the old pointer to be set to NULL
1095 */
1096 void *_talloc_move(const void *new_ctx, const void *_pptr)
1097 {
1098         const void **pptr = discard_const_p(const void *,_pptr);
1099         void *ret = _talloc_steal(new_ctx, *pptr);
1100         (*pptr) = NULL;
1101         return ret;
1102 }
1103
1104 /*
1105   return the total size of a talloc pool (subtree)
1106 */
1107 size_t talloc_total_size(const void *ptr)
1108 {
1109         size_t total = 0;
1110         struct talloc_chunk *c, *tc;
1111
1112         if (ptr == NULL) {
1113                 ptr = null_context;
1114         }
1115         if (ptr == NULL) {
1116                 return 0;
1117         }
1118
1119         tc = talloc_chunk_from_ptr(ptr);
1120
1121         if (tc->flags & TALLOC_FLAG_LOOP) {
1122                 return 0;
1123         }
1124
1125         tc->flags |= TALLOC_FLAG_LOOP;
1126
1127         total = tc->size;
1128         for (c=tc->child;c;c=c->next) {
1129                 total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
1130         }
1131
1132         tc->flags &= ~TALLOC_FLAG_LOOP;
1133
1134         return total;
1135 }
1136
1137 /*
1138   return the total number of blocks in a talloc pool (subtree)
1139 */
1140 size_t talloc_total_blocks(const void *ptr)
1141 {
1142         size_t total = 0;
1143         struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
1144
1145         if (tc->flags & TALLOC_FLAG_LOOP) {
1146                 return 0;
1147         }
1148
1149         tc->flags |= TALLOC_FLAG_LOOP;
1150
1151         total++;
1152         for (c=tc->child;c;c=c->next) {
1153                 total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
1154         }
1155
1156         tc->flags &= ~TALLOC_FLAG_LOOP;
1157
1158         return total;
1159 }
1160
1161 /*
1162   return the number of external references to a pointer
1163 */
1164 size_t talloc_reference_count(const void *ptr)
1165 {
1166         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1167         struct talloc_reference_handle *h;
1168         size_t ret = 0;
1169
1170         for (h=tc->refs;h;h=h->next) {
1171                 ret++;
1172         }
1173         return ret;
1174 }
1175
1176 /*
1177   report on memory usage by all children of a pointer, giving a full tree view
1178 */
1179 void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
1180                             void (*callback)(const void *ptr,
1181                                              int depth, int max_depth,
1182                                              int is_ref,
1183                                              void *private_data),
1184                             void *private_data)
1185 {
1186         struct talloc_chunk *c, *tc;
1187
1188         if (ptr == NULL) {
1189                 ptr = null_context;
1190         }
1191         if (ptr == NULL) return;
1192
1193         tc = talloc_chunk_from_ptr(ptr);
1194
1195         if (tc->flags & TALLOC_FLAG_LOOP) {
1196                 return;
1197         }
1198
1199         callback(ptr, depth, max_depth, 0, private_data);
1200
1201         if (max_depth >= 0 && depth >= max_depth) {
1202                 return;
1203         }
1204
1205         tc->flags |= TALLOC_FLAG_LOOP;
1206         for (c=tc->child;c;c=c->next) {
1207                 if (c->name == TALLOC_MAGIC_REFERENCE) {
1208                         struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
1209                         callback(h->ptr, depth + 1, max_depth, 1, private_data);
1210                 } else {
1211                         talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
1212                 }
1213         }
1214         tc->flags &= ~TALLOC_FLAG_LOOP;
1215 }
1216
1217 static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
1218 {
1219         const char *name = talloc_get_name(ptr);
1220         FILE *f = (FILE *)_f;
1221
1222         if (is_ref) {
1223                 fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
1224                 return;
1225         }
1226
1227         if (depth == 0) {
1228                 fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n", 
1229                         (max_depth < 0 ? "full " :""), name,
1230                         (unsigned long)talloc_total_size(ptr),
1231                         (unsigned long)talloc_total_blocks(ptr));
1232                 return;
1233         }
1234
1235         fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n", 
1236                 depth*4, "",
1237                 name,
1238                 (unsigned long)talloc_total_size(ptr),
1239                 (unsigned long)talloc_total_blocks(ptr),
1240                 (int)talloc_reference_count(ptr), ptr);
1241
1242 #if 0
1243         fprintf(f, "content: ");
1244         if (talloc_total_size(ptr)) {
1245                 int tot = talloc_total_size(ptr);
1246                 int i;
1247
1248                 for (i = 0; i < tot; i++) {
1249                         if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
1250                                 fprintf(f, "%c", ((char *)ptr)[i]);
1251                         } else {
1252                                 fprintf(f, "~%02x", ((char *)ptr)[i]);
1253                         }
1254                 }
1255         }
1256         fprintf(f, "\n");
1257 #endif
1258 }
1259
1260 /*
1261   report on memory usage by all children of a pointer, giving a full tree view
1262 */
1263 void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
1264 {
1265         talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
1266         fflush(f);
1267 }
1268
1269 /*
1270   report on memory usage by all children of a pointer, giving a full tree view
1271 */
1272 void talloc_report_full(const void *ptr, FILE *f)
1273 {
1274         talloc_report_depth_file(ptr, 0, -1, f);
1275 }
1276
1277 /*
1278   report on memory usage by all children of a pointer
1279 */
1280 void talloc_report(const void *ptr, FILE *f)
1281 {
1282         talloc_report_depth_file(ptr, 0, 1, f);
1283 }
1284
1285 /*
1286   report on any memory hanging off the null context
1287 */
1288 static void talloc_report_null(void)
1289 {
1290         if (talloc_total_size(null_context) != 0) {
1291                 talloc_report(null_context, stderr);
1292         }
1293 }
1294
1295 /*
1296   report on any memory hanging off the null context
1297 */
1298 static void talloc_report_null_full(void)
1299 {
1300         if (talloc_total_size(null_context) != 0) {
1301                 talloc_report_full(null_context, stderr);
1302         }
1303 }
1304
1305 /*
1306   enable tracking of the NULL context
1307 */
1308 void talloc_enable_null_tracking(void)
1309 {
1310         if (null_context == NULL) {
1311                 null_context = _talloc_named_const(NULL, 0, "null_context");
1312         }
1313 }
1314
1315 /*
1316   disable tracking of the NULL context
1317 */
1318 void talloc_disable_null_tracking(void)
1319 {
1320         _talloc_free(null_context);
1321         null_context = NULL;
1322 }
1323
1324 /*
1325   enable leak reporting on exit
1326 */
1327 void talloc_enable_leak_report(void)
1328 {
1329         talloc_enable_null_tracking();
1330         atexit(talloc_report_null);
1331 }
1332
1333 /*
1334   enable full leak reporting on exit
1335 */
1336 void talloc_enable_leak_report_full(void)
1337 {
1338         talloc_enable_null_tracking();
1339         atexit(talloc_report_null_full);
1340 }
1341
1342 /* 
1343    talloc and zero memory. 
1344 */
1345 void *_talloc_zero(const void *ctx, size_t size, const char *name)
1346 {
1347         void *p = _talloc_named_const(ctx, size, name);
1348
1349         if (p) {
1350                 memset(p, '\0', size);
1351         }
1352
1353         return p;
1354 }
1355
1356 /*
1357   memdup with a talloc. 
1358 */
1359 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
1360 {
1361         void *newp = _talloc_named_const(t, size, name);
1362
1363         if (likely(newp)) {
1364                 memcpy(newp, p, size);
1365         }
1366
1367         return newp;
1368 }
1369
1370 static inline char *__talloc_strlendup(const void *t, const char *p, size_t len)
1371 {
1372         char *ret;
1373
1374         ret = (char *)__talloc(t, len + 1);
1375         if (unlikely(!ret)) return NULL;
1376
1377         memcpy(ret, p, len);
1378         ret[len] = 0;
1379
1380         _talloc_set_name_const(ret, ret);
1381         return ret;
1382 }
1383
1384 /*
1385   strdup with a talloc
1386 */
1387 char *talloc_strdup(const void *t, const char *p)
1388 {
1389         if (unlikely(!p)) return NULL;
1390         return __talloc_strlendup(t, p, strlen(p));
1391 }
1392
1393 /*
1394   strndup with a talloc
1395 */
1396 char *talloc_strndup(const void *t, const char *p, size_t n)
1397 {
1398         if (unlikely(!p)) return NULL;
1399         return __talloc_strlendup(t, p, strnlen(p, n));
1400 }
1401
1402 static inline char *__talloc_strlendup_append(char *s, size_t slen,
1403                                               const char *a, size_t alen)
1404 {
1405         char *ret;
1406
1407         ret = talloc_realloc(NULL, s, char, slen + alen + 1);
1408         if (unlikely(!ret)) return NULL;
1409
1410         /* append the string and the trailing \0 */
1411         memcpy(&ret[slen], a, alen);
1412         ret[slen+alen] = 0;
1413
1414         _talloc_set_name_const(ret, ret);
1415         return ret;
1416 }
1417
1418 /*
1419  * Appends at the end of the string.
1420  */
1421 char *talloc_strdup_append(char *s, const char *a)
1422 {
1423         if (unlikely(!s)) {
1424                 return talloc_strdup(NULL, a);
1425         }
1426
1427         if (unlikely(!a)) {
1428                 return s;
1429         }
1430
1431         return __talloc_strlendup_append(s, strlen(s), a, strlen(a));
1432 }
1433
1434 /*
1435  * Appends at the end of the talloc'ed buffer,
1436  * not the end of the string.
1437  */
1438 char *talloc_strdup_append_buffer(char *s, const char *a)
1439 {
1440         size_t slen;
1441
1442         if (unlikely(!s)) {
1443                 return talloc_strdup(NULL, a);
1444         }
1445
1446         if (unlikely(!a)) {
1447                 return s;
1448         }
1449
1450         slen = talloc_get_size(s);
1451         if (likely(slen > 0)) {
1452                 slen--;
1453         }
1454
1455         return __talloc_strlendup_append(s, slen, a, strlen(a));
1456 }
1457
1458 /*
1459  * Appends at the end of the string.
1460  */
1461 char *talloc_strndup_append(char *s, const char *a, size_t n)
1462 {
1463         if (unlikely(!s)) {
1464                 return talloc_strdup(NULL, a);
1465         }
1466
1467         if (unlikely(!a)) {
1468                 return s;
1469         }
1470
1471         return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n));
1472 }
1473
1474 /*
1475  * Appends at the end of the talloc'ed buffer,
1476  * not the end of the string.
1477  */
1478 char *talloc_strndup_append_buffer(char *s, const char *a, size_t n)
1479 {
1480         size_t slen;
1481
1482         if (unlikely(!s)) {
1483                 return talloc_strdup(NULL, a);
1484         }
1485
1486         if (unlikely(!a)) {
1487                 return s;
1488         }
1489
1490         slen = talloc_get_size(s);
1491         if (likely(slen > 0)) {
1492                 slen--;
1493         }
1494
1495         return __talloc_strlendup_append(s, slen, a, strnlen(a, n));
1496 }
1497
1498 #ifndef HAVE_VA_COPY
1499 #ifdef HAVE___VA_COPY
1500 #define va_copy(dest, src) __va_copy(dest, src)
1501 #else
1502 #define va_copy(dest, src) (dest) = (src)
1503 #endif
1504 #endif
1505
1506 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1507 {
1508         int len;
1509         char *ret;
1510         va_list ap2;
1511         char c;
1512
1513         /* this call looks strange, but it makes it work on older solaris boxes */
1514         va_copy(ap2, ap);
1515         len = vsnprintf(&c, 1, fmt, ap2);
1516         va_end(ap2);
1517         if (unlikely(len < 0)) {
1518                 return NULL;
1519         }
1520
1521         ret = (char *)__talloc(t, len+1);
1522         if (unlikely(!ret)) return NULL;
1523
1524         va_copy(ap2, ap);
1525         vsnprintf(ret, len+1, fmt, ap2);
1526         va_end(ap2);
1527
1528         _talloc_set_name_const(ret, ret);
1529         return ret;
1530 }
1531
1532
1533 /*
1534   Perform string formatting, and return a pointer to newly allocated
1535   memory holding the result, inside a memory pool.
1536  */
1537 char *talloc_asprintf(const void *t, const char *fmt, ...)
1538 {
1539         va_list ap;
1540         char *ret;
1541
1542         va_start(ap, fmt);
1543         ret = talloc_vasprintf(t, fmt, ap);
1544         va_end(ap);
1545         return ret;
1546 }
1547
1548 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
1549                                                  const char *fmt, va_list ap)
1550                                                  PRINTF_ATTRIBUTE(3,0);
1551
1552 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
1553                                                  const char *fmt, va_list ap)
1554 {
1555         ssize_t alen;
1556         va_list ap2;
1557         char c;
1558
1559         va_copy(ap2, ap);
1560         alen = vsnprintf(&c, 1, fmt, ap2);
1561         va_end(ap2);
1562
1563         if (alen <= 0) {
1564                 /* Either the vsnprintf failed or the format resulted in
1565                  * no characters being formatted. In the former case, we
1566                  * ought to return NULL, in the latter we ought to return
1567                  * the original string. Most current callers of this
1568                  * function expect it to never return NULL.
1569                  */
1570                 return s;
1571         }
1572
1573         s = talloc_realloc(NULL, s, char, slen + alen + 1);
1574         if (!s) return NULL;
1575
1576         va_copy(ap2, ap);
1577         vsnprintf(s + slen, alen + 1, fmt, ap2);
1578         va_end(ap2);
1579
1580         _talloc_set_name_const(s, s);
1581         return s;
1582 }
1583
1584 /**
1585  * Realloc @p s to append the formatted result of @p fmt and @p ap,
1586  * and return @p s, which may have moved.  Good for gradually
1587  * accumulating output into a string buffer. Appends at the end
1588  * of the string.
1589  **/
1590 char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1591 {
1592         if (unlikely(!s)) {
1593                 return talloc_vasprintf(NULL, fmt, ap);
1594         }
1595
1596         return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap);
1597 }
1598
1599 /**
1600  * Realloc @p s to append the formatted result of @p fmt and @p ap,
1601  * and return @p s, which may have moved. Always appends at the
1602  * end of the talloc'ed buffer, not the end of the string.
1603  **/
1604 char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap)
1605 {
1606         size_t slen;
1607
1608         if (unlikely(!s)) {
1609                 return talloc_vasprintf(NULL, fmt, ap);
1610         }
1611
1612         slen = talloc_get_size(s);
1613         if (likely(slen > 0)) {
1614                 slen--;
1615         }
1616
1617         return __talloc_vaslenprintf_append(s, slen, fmt, ap);
1618 }
1619
1620 /*
1621   Realloc @p s to append the formatted result of @p fmt and return @p
1622   s, which may have moved.  Good for gradually accumulating output
1623   into a string buffer.
1624  */
1625 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1626 {
1627         va_list ap;
1628
1629         va_start(ap, fmt);
1630         s = talloc_vasprintf_append(s, fmt, ap);
1631         va_end(ap);
1632         return s;
1633 }
1634
1635 /*
1636   Realloc @p s to append the formatted result of @p fmt and return @p
1637   s, which may have moved.  Good for gradually accumulating output
1638   into a buffer.
1639  */
1640 char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...)
1641 {
1642         va_list ap;
1643
1644         va_start(ap, fmt);
1645         s = talloc_vasprintf_append_buffer(s, fmt, ap);
1646         va_end(ap);
1647         return s;
1648 }
1649
1650 /*
1651   alloc an array, checking for integer overflow in the array size
1652 */
1653 void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1654 {
1655         if (count >= MAX_TALLOC_SIZE/el_size) {
1656                 return NULL;
1657         }
1658         return _talloc_named_const(ctx, el_size * count, name);
1659 }
1660
1661 /*
1662   alloc an zero array, checking for integer overflow in the array size
1663 */
1664 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1665 {
1666         if (count >= MAX_TALLOC_SIZE/el_size) {
1667                 return NULL;
1668         }
1669         return _talloc_zero(ctx, el_size * count, name);
1670 }
1671
1672 /*
1673   realloc an array, checking for integer overflow in the array size
1674 */
1675 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1676 {
1677         if (count >= MAX_TALLOC_SIZE/el_size) {
1678                 return NULL;
1679         }
1680         return _talloc_realloc(ctx, ptr, el_size * count, name);
1681 }
1682
1683 /*
1684   a function version of talloc_realloc(), so it can be passed as a function pointer
1685   to libraries that want a realloc function (a realloc function encapsulates
1686   all the basic capabilities of an allocation library, which is why this is useful)
1687 */
1688 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1689 {
1690         return _talloc_realloc(context, ptr, size, NULL);
1691 }
1692
1693
1694 static int talloc_autofree_destructor(void *ptr)
1695 {
1696         autofree_context = NULL;
1697         return 0;
1698 }
1699
1700 static void talloc_autofree(void)
1701 {
1702         _talloc_free(autofree_context);
1703 }
1704
1705 /*
1706   return a context which will be auto-freed on exit
1707   this is useful for reducing the noise in leak reports
1708 */
1709 void *talloc_autofree_context(void)
1710 {
1711         if (autofree_context == NULL) {
1712                 autofree_context = _talloc_named_const(NULL, 0, "autofree_context");
1713                 talloc_set_destructor(autofree_context, talloc_autofree_destructor);
1714                 atexit(talloc_autofree);
1715         }
1716         return autofree_context;
1717 }
1718
1719 size_t talloc_get_size(const void *context)
1720 {
1721         struct talloc_chunk *tc;
1722
1723         if (context == NULL)
1724                 return 0;
1725
1726         tc = talloc_chunk_from_ptr(context);
1727
1728         return tc->size;
1729 }
1730
1731 /*
1732   find a parent of this context that has the given name, if any
1733 */
1734 void *talloc_find_parent_byname(const void *context, const char *name)
1735 {
1736         struct talloc_chunk *tc;
1737
1738         if (context == NULL) {
1739                 return NULL;
1740         }
1741
1742         tc = talloc_chunk_from_ptr(context);
1743         while (tc) {
1744                 if (tc->name && strcmp(tc->name, name) == 0) {
1745                         return TC_PTR_FROM_CHUNK(tc);
1746                 }
1747                 while (tc && tc->prev) tc = tc->prev;
1748                 if (tc) {
1749                         tc = tc->parent;
1750                 }
1751         }
1752         return NULL;
1753 }
1754
1755 /*
1756   show the parentage of a context
1757 */
1758 void talloc_show_parents(const void *context, FILE *file)
1759 {
1760         struct talloc_chunk *tc;
1761
1762         if (context == NULL) {
1763                 fprintf(file, "talloc no parents for NULL\n");
1764                 return;
1765         }
1766
1767         tc = talloc_chunk_from_ptr(context);
1768         fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
1769         while (tc) {
1770                 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
1771                 while (tc && tc->prev) tc = tc->prev;
1772                 if (tc) {
1773                         tc = tc->parent;
1774                 }
1775         }
1776         fflush(file);
1777 }
1778
1779 /*
1780   return 1 if ptr is a parent of context
1781 */
1782 int talloc_is_parent(const void *context, const void *ptr)
1783 {
1784         struct talloc_chunk *tc;
1785
1786         if (context == NULL) {
1787                 return 0;
1788         }
1789
1790         tc = talloc_chunk_from_ptr(context);
1791         while (tc) {
1792                 if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
1793                 while (tc && tc->prev) tc = tc->prev;
1794                 if (tc) {
1795                         tc = tc->parent;
1796                 }
1797         }
1798         return 0;
1799 }