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