Revert "prevent git ref/unref mismatches. prevent reference promotion to owner"
[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                 if (is_child) {
514                         _talloc_free(tc->refs);
515                         return _talloc_free(ptr);
516                 } else {
517                         /* the first reference becomes the owner */
518                         _talloc_steal(talloc_parent(tc->refs), ptr);
519                         _talloc_free(tc->refs);
520                 }
521                 return -1;
522         }
523
524         if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) {
525                 /* we have a free loop - stop looping */
526                 return 0;
527         }
528
529         if (unlikely(tc->destructor)) {
530                 talloc_destructor_t d = tc->destructor;
531                 if (d == (talloc_destructor_t)-1) {
532                         return -1;
533                 }
534                 tc->destructor = (talloc_destructor_t)-1;
535                 if (d(ptr) == -1) {
536                         tc->destructor = d;
537                         return -1;
538                 }
539                 tc->destructor = NULL;
540         }
541
542         if (tc->parent) {
543                 _TLIST_REMOVE(tc->parent->child, tc);
544                 if (tc->parent->child) {
545                         tc->parent->child->parent = tc->parent;
546                 }
547         } else {
548                 if (tc->prev) tc->prev->next = tc->next;
549                 if (tc->next) tc->next->prev = tc->prev;
550         }
551
552         tc->flags |= TALLOC_FLAG_LOOP;
553
554         while (tc->child) {
555                 /* we need to work out who will own an abandoned child
556                    if it cannot be freed. In priority order, the first
557                    choice is owner of any remaining reference to this
558                    pointer, the second choice is our parent, and the
559                    final choice is the null context. */
560                 void *child = TC_PTR_FROM_CHUNK(tc->child);
561                 const void *new_parent = null_context;
562                 if (unlikely(tc->child->refs)) {
563                         struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
564                         if (p) new_parent = TC_PTR_FROM_CHUNK(p);
565                 }
566                 if (unlikely(_talloc_free(child) == -1)) {
567                         if (new_parent == null_context) {
568                                 struct talloc_chunk *p = talloc_parent_chunk(ptr);
569                                 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
570                         }
571                         talloc_steal(new_parent, child);
572                 }
573         }
574
575         tc->flags |= TALLOC_FLAG_FREE;
576
577         if (tc->flags & (TALLOC_FLAG_POOL|TALLOC_FLAG_POOLMEM)) {
578                 struct talloc_chunk *pool;
579                 unsigned int *pool_object_count;
580
581                 pool = (tc->flags & TALLOC_FLAG_POOL)
582                         ? tc : (struct talloc_chunk *)tc->pool;
583
584                 pool_object_count = talloc_pool_objectcount(pool);
585
586                 if (*pool_object_count == 0) {
587                         talloc_abort("Pool object count zero!");
588                 }
589
590                 *pool_object_count -= 1;
591
592                 if (*pool_object_count == 0) {
593                         free(pool);
594                 }
595         }
596         else {
597                 free(tc);
598         }
599         return 0;
600 }
601
602 /* 
603    move a lump of memory from one talloc context to another return the
604    ptr on success, or NULL if it could not be transferred.
605    passing NULL as ptr will always return NULL with no side effects.
606 */
607 void *_talloc_steal(const void *new_ctx, const void *ptr)
608 {
609         struct talloc_chunk *tc, *new_tc;
610
611         if (unlikely(!ptr)) {
612                 return NULL;
613         }
614
615         if (unlikely(new_ctx == NULL)) {
616                 new_ctx = null_context;
617         }
618
619         tc = talloc_chunk_from_ptr(ptr);
620
621         if (unlikely(new_ctx == NULL)) {
622                 if (tc->parent) {
623                         _TLIST_REMOVE(tc->parent->child, tc);
624                         if (tc->parent->child) {
625                                 tc->parent->child->parent = tc->parent;
626                         }
627                 } else {
628                         if (tc->prev) tc->prev->next = tc->next;
629                         if (tc->next) tc->next->prev = tc->prev;
630                 }
631                 
632                 tc->parent = tc->next = tc->prev = NULL;
633                 return discard_const_p(void, ptr);
634         }
635
636         new_tc = talloc_chunk_from_ptr(new_ctx);
637
638         if (unlikely(tc == new_tc || tc->parent == new_tc)) {
639                 return discard_const_p(void, ptr);
640         }
641
642         if (tc->parent) {
643                 _TLIST_REMOVE(tc->parent->child, tc);
644                 if (tc->parent->child) {
645                         tc->parent->child->parent = tc->parent;
646                 }
647         } else {
648                 if (tc->prev) tc->prev->next = tc->next;
649                 if (tc->next) tc->next->prev = tc->prev;
650         }
651
652         tc->parent = new_tc;
653         if (new_tc->child) new_tc->child->parent = NULL;
654         _TLIST_ADD(new_tc->child, tc);
655
656         return discard_const_p(void, ptr);
657 }
658
659
660
661 /*
662   remove a secondary reference to a pointer. This undo's what
663   talloc_reference() has done. The context and pointer arguments
664   must match those given to a talloc_reference()
665 */
666 static inline int talloc_unreference(const void *context, const void *ptr)
667 {
668         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
669         struct talloc_reference_handle *h;
670
671         if (unlikely(context == NULL)) {
672                 context = null_context;
673         }
674
675         for (h=tc->refs;h;h=h->next) {
676                 struct talloc_chunk *p = talloc_parent_chunk(h);
677                 if (p == NULL) {
678                         if (context == NULL) break;
679                 } else if (TC_PTR_FROM_CHUNK(p) == context) {
680                         break;
681                 }
682         }
683         if (h == NULL) {
684                 return -1;
685         }
686
687         return _talloc_free(h);
688 }
689
690 /*
691   remove a specific parent context from a pointer. This is a more
692   controlled varient of talloc_free()
693 */
694 int talloc_unlink(const void *context, void *ptr)
695 {
696         struct talloc_chunk *tc_p, *new_p;
697         void *new_parent;
698
699         if (ptr == NULL) {
700                 return -1;
701         }
702
703         if (context == NULL) {
704                 context = null_context;
705         }
706
707         if (talloc_unreference(context, ptr) == 0) {
708                 return 0;
709         }
710
711         if (context == NULL) {
712                 if (talloc_parent_chunk(ptr) != NULL) {
713                         return -1;
714                 }
715         } else {
716                 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
717                         return -1;
718                 }
719         }
720         
721         tc_p = talloc_chunk_from_ptr(ptr);
722
723         if (tc_p->refs == NULL) {
724                 return _talloc_free(ptr);
725         }
726
727         new_p = talloc_parent_chunk(tc_p->refs);
728         if (new_p) {
729                 new_parent = TC_PTR_FROM_CHUNK(new_p);
730         } else {
731                 new_parent = NULL;
732         }
733
734         if (talloc_unreference(new_parent, ptr) != 0) {
735                 return -1;
736         }
737
738         talloc_steal(new_parent, ptr);
739
740         return 0;
741 }
742
743 /*
744   add a name to an existing pointer - va_list version
745 */
746 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
747
748 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
749 {
750         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
751         tc->name = talloc_vasprintf(ptr, fmt, ap);
752         if (likely(tc->name)) {
753                 _talloc_set_name_const(tc->name, ".name");
754         }
755         return tc->name;
756 }
757
758 /*
759   add a name to an existing pointer
760 */
761 const char *talloc_set_name(const void *ptr, const char *fmt, ...)
762 {
763         const char *name;
764         va_list ap;
765         va_start(ap, fmt);
766         name = talloc_set_name_v(ptr, fmt, ap);
767         va_end(ap);
768         return name;
769 }
770
771
772 /*
773   create a named talloc pointer. Any talloc pointer can be named, and
774   talloc_named() operates just like talloc() except that it allows you
775   to name the pointer.
776 */
777 void *talloc_named(const void *context, size_t size, const char *fmt, ...)
778 {
779         va_list ap;
780         void *ptr;
781         const char *name;
782
783         ptr = __talloc(context, size);
784         if (unlikely(ptr == NULL)) return NULL;
785
786         va_start(ap, fmt);
787         name = talloc_set_name_v(ptr, fmt, ap);
788         va_end(ap);
789
790         if (unlikely(name == NULL)) {
791                 _talloc_free(ptr);
792                 return NULL;
793         }
794
795         return ptr;
796 }
797
798 /*
799   return the name of a talloc ptr, or "UNNAMED"
800 */
801 const char *talloc_get_name(const void *ptr)
802 {
803         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
804         if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
805                 return ".reference";
806         }
807         if (likely(tc->name)) {
808                 return tc->name;
809         }
810         return "UNNAMED";
811 }
812
813
814 /*
815   check if a pointer has the given name. If it does, return the pointer,
816   otherwise return NULL
817 */
818 void *talloc_check_name(const void *ptr, const char *name)
819 {
820         const char *pname;
821         if (unlikely(ptr == NULL)) return NULL;
822         pname = talloc_get_name(ptr);
823         if (likely(pname == name || strcmp(pname, name) == 0)) {
824                 return discard_const_p(void, ptr);
825         }
826         return NULL;
827 }
828
829 static void talloc_abort_type_missmatch(const char *location,
830                                         const char *name,
831                                         const char *expected)
832 {
833         const char *reason;
834
835         reason = talloc_asprintf(NULL,
836                                  "%s: Type mismatch: name[%s] expected[%s]",
837                                  location,
838                                  name?name:"NULL",
839                                  expected);
840         if (!reason) {
841                 reason = "Type mismatch";
842         }
843
844         talloc_abort(reason);
845 }
846
847 void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location)
848 {
849         const char *pname;
850
851         if (unlikely(ptr == NULL)) {
852                 talloc_abort_type_missmatch(location, NULL, name);
853                 return NULL;
854         }
855
856         pname = talloc_get_name(ptr);
857         if (likely(pname == name || strcmp(pname, name) == 0)) {
858                 return discard_const_p(void, ptr);
859         }
860
861         talloc_abort_type_missmatch(location, pname, name);
862         return NULL;
863 }
864
865 /*
866   this is for compatibility with older versions of talloc
867 */
868 void *talloc_init(const char *fmt, ...)
869 {
870         va_list ap;
871         void *ptr;
872         const char *name;
873
874         /*
875          * samba3 expects talloc_report_depth_cb(NULL, ...)
876          * reports all talloc'ed memory, so we need to enable
877          * null_tracking
878          */
879         talloc_enable_null_tracking();
880
881         ptr = __talloc(NULL, 0);
882         if (unlikely(ptr == NULL)) return NULL;
883
884         va_start(ap, fmt);
885         name = talloc_set_name_v(ptr, fmt, ap);
886         va_end(ap);
887
888         if (unlikely(name == NULL)) {
889                 _talloc_free(ptr);
890                 return NULL;
891         }
892
893         return ptr;
894 }
895
896 /*
897   this is a replacement for the Samba3 talloc_destroy_pool functionality. It
898   should probably not be used in new code. It's in here to keep the talloc
899   code consistent across Samba 3 and 4.
900 */
901 void talloc_free_children(void *ptr)
902 {
903         struct talloc_chunk *tc;
904
905         if (unlikely(ptr == NULL)) {
906                 return;
907         }
908
909         tc = talloc_chunk_from_ptr(ptr);
910
911         while (tc->child) {
912                 /* we need to work out who will own an abandoned child
913                    if it cannot be freed. In priority order, the first
914                    choice is owner of any remaining reference to this
915                    pointer, the second choice is our parent, and the
916                    final choice is the null context. */
917                 void *child = TC_PTR_FROM_CHUNK(tc->child);
918                 const void *new_parent = null_context;
919                 if (unlikely(tc->child->refs)) {
920                         struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
921                         if (p) new_parent = TC_PTR_FROM_CHUNK(p);
922                 }
923                 if (unlikely(_talloc_free(child) == -1)) {
924                         if (new_parent == null_context) {
925                                 struct talloc_chunk *p = talloc_parent_chunk(ptr);
926                                 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
927                         }
928                         talloc_steal(new_parent, child);
929                 }
930         }
931
932         if ((tc->flags & TALLOC_FLAG_POOL)
933             && (*talloc_pool_objectcount(tc) == 1)) {
934                 tc->pool = ((char *)tc + TC_HDR_SIZE + TALLOC_POOL_HDR_SIZE);
935 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
936                 VALGRIND_MAKE_MEM_NOACCESS(
937                         tc->pool, tc->size - TALLOC_POOL_HDR_SIZE);
938 #endif
939         }
940 }
941
942 /* 
943    Allocate a bit of memory as a child of an existing pointer
944 */
945 void *_talloc(const void *context, size_t size)
946 {
947         return __talloc(context, size);
948 }
949
950 /*
951   externally callable talloc_set_name_const()
952 */
953 void talloc_set_name_const(const void *ptr, const char *name)
954 {
955         _talloc_set_name_const(ptr, name);
956 }
957
958 /*
959   create a named talloc pointer. Any talloc pointer can be named, and
960   talloc_named() operates just like talloc() except that it allows you
961   to name the pointer.
962 */
963 void *talloc_named_const(const void *context, size_t size, const char *name)
964 {
965         return _talloc_named_const(context, size, name);
966 }
967
968 /* 
969    free a talloc pointer. This also frees all child pointers of this 
970    pointer recursively
971
972    return 0 if the memory is actually freed, otherwise -1. The memory
973    will not be freed if the ref_count is > 1 or the destructor (if
974    any) returns non-zero
975 */
976 int talloc_free(void *ptr)
977 {
978         return _talloc_free(ptr);
979 }
980
981
982
983 /*
984   A talloc version of realloc. The context argument is only used if
985   ptr is NULL
986 */
987 void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
988 {
989         struct talloc_chunk *tc;
990         void *new_ptr;
991         bool malloced = false;
992
993         /* size zero is equivalent to free() */
994         if (unlikely(size == 0)) {
995                 _talloc_free(ptr);
996                 return NULL;
997         }
998
999         if (unlikely(size >= MAX_TALLOC_SIZE)) {
1000                 return NULL;
1001         }
1002
1003         /* realloc(NULL) is equivalent to malloc() */
1004         if (ptr == NULL) {
1005                 return _talloc_named_const(context, size, name);
1006         }
1007
1008         tc = talloc_chunk_from_ptr(ptr);
1009
1010         /* don't allow realloc on referenced pointers */
1011         if (unlikely(tc->refs)) {
1012                 return NULL;
1013         }
1014
1015         /* don't let anybody try to realloc a talloc_pool */
1016         if (unlikely(tc->flags & TALLOC_FLAG_POOL)) {
1017                 return NULL;
1018         }
1019
1020         /* don't shrink if we have less than 1k to gain */
1021         if ((size < tc->size) && ((tc->size - size) < 1024)) {
1022                 tc->size = size;
1023                 return ptr;
1024         }
1025
1026         /* by resetting magic we catch users of the old memory */
1027         tc->flags |= TALLOC_FLAG_FREE;
1028
1029 #if ALWAYS_REALLOC
1030         new_ptr = malloc(size + TC_HDR_SIZE);
1031         if (new_ptr) {
1032                 memcpy(new_ptr, tc, tc->size + TC_HDR_SIZE);
1033                 free(tc);
1034         }
1035 #else
1036         if (tc->flags & TALLOC_FLAG_POOLMEM) {
1037
1038                 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE);
1039                 *talloc_pool_objectcount((struct talloc_chunk *)
1040                                          (tc->pool)) -= 1;
1041
1042                 if (new_ptr == NULL) {
1043                         new_ptr = malloc(TC_HDR_SIZE+size);
1044                         malloced = true;
1045                 }
1046
1047                 if (new_ptr) {
1048                         memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
1049                 }
1050         }
1051         else {
1052                 new_ptr = realloc(tc, size + TC_HDR_SIZE);
1053         }
1054 #endif
1055         if (unlikely(!new_ptr)) {       
1056                 tc->flags &= ~TALLOC_FLAG_FREE; 
1057                 return NULL; 
1058         }
1059
1060         tc = (struct talloc_chunk *)new_ptr;
1061         tc->flags &= ~TALLOC_FLAG_FREE;
1062         if (malloced) {
1063                 tc->flags &= ~TALLOC_FLAG_POOLMEM;
1064         }
1065         if (tc->parent) {
1066                 tc->parent->child = tc;
1067         }
1068         if (tc->child) {
1069                 tc->child->parent = tc;
1070         }
1071
1072         if (tc->prev) {
1073                 tc->prev->next = tc;
1074         }
1075         if (tc->next) {
1076                 tc->next->prev = tc;
1077         }
1078
1079         tc->size = size;
1080         _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
1081
1082         return TC_PTR_FROM_CHUNK(tc);
1083 }
1084
1085 /*
1086   a wrapper around talloc_steal() for situations where you are moving a pointer
1087   between two structures, and want the old pointer to be set to NULL
1088 */
1089 void *_talloc_move(const void *new_ctx, const void *_pptr)
1090 {
1091         const void **pptr = discard_const_p(const void *,_pptr);
1092         void *ret = _talloc_steal(new_ctx, *pptr);
1093         (*pptr) = NULL;
1094         return ret;
1095 }
1096
1097 /*
1098   return the total size of a talloc pool (subtree)
1099 */
1100 size_t talloc_total_size(const void *ptr)
1101 {
1102         size_t total = 0;
1103         struct talloc_chunk *c, *tc;
1104
1105         if (ptr == NULL) {
1106                 ptr = null_context;
1107         }
1108         if (ptr == NULL) {
1109                 return 0;
1110         }
1111
1112         tc = talloc_chunk_from_ptr(ptr);
1113
1114         if (tc->flags & TALLOC_FLAG_LOOP) {
1115                 return 0;
1116         }
1117
1118         tc->flags |= TALLOC_FLAG_LOOP;
1119
1120         total = tc->size;
1121         for (c=tc->child;c;c=c->next) {
1122                 total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
1123         }
1124
1125         tc->flags &= ~TALLOC_FLAG_LOOP;
1126
1127         return total;
1128 }
1129
1130 /*
1131   return the total number of blocks in a talloc pool (subtree)
1132 */
1133 size_t talloc_total_blocks(const void *ptr)
1134 {
1135         size_t total = 0;
1136         struct talloc_chunk *c, *tc = talloc_chunk_from_ptr(ptr);
1137
1138         if (tc->flags & TALLOC_FLAG_LOOP) {
1139                 return 0;
1140         }
1141
1142         tc->flags |= TALLOC_FLAG_LOOP;
1143
1144         total++;
1145         for (c=tc->child;c;c=c->next) {
1146                 total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
1147         }
1148
1149         tc->flags &= ~TALLOC_FLAG_LOOP;
1150
1151         return total;
1152 }
1153
1154 /*
1155   return the number of external references to a pointer
1156 */
1157 size_t talloc_reference_count(const void *ptr)
1158 {
1159         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1160         struct talloc_reference_handle *h;
1161         size_t ret = 0;
1162
1163         for (h=tc->refs;h;h=h->next) {
1164                 ret++;
1165         }
1166         return ret;
1167 }
1168
1169 /*
1170   report on memory usage by all children of a pointer, giving a full tree view
1171 */
1172 void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
1173                             void (*callback)(const void *ptr,
1174                                              int depth, int max_depth,
1175                                              int is_ref,
1176                                              void *private_data),
1177                             void *private_data)
1178 {
1179         struct talloc_chunk *c, *tc;
1180
1181         if (ptr == NULL) {
1182                 ptr = null_context;
1183         }
1184         if (ptr == NULL) return;
1185
1186         tc = talloc_chunk_from_ptr(ptr);
1187
1188         if (tc->flags & TALLOC_FLAG_LOOP) {
1189                 return;
1190         }
1191
1192         callback(ptr, depth, max_depth, 0, private_data);
1193
1194         if (max_depth >= 0 && depth >= max_depth) {
1195                 return;
1196         }
1197
1198         tc->flags |= TALLOC_FLAG_LOOP;
1199         for (c=tc->child;c;c=c->next) {
1200                 if (c->name == TALLOC_MAGIC_REFERENCE) {
1201                         struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
1202                         callback(h->ptr, depth + 1, max_depth, 1, private_data);
1203                 } else {
1204                         talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
1205                 }
1206         }
1207         tc->flags &= ~TALLOC_FLAG_LOOP;
1208 }
1209
1210 static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
1211 {
1212         const char *name = talloc_get_name(ptr);
1213         FILE *f = (FILE *)_f;
1214
1215         if (is_ref) {
1216                 fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
1217                 return;
1218         }
1219
1220         if (depth == 0) {
1221                 fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n", 
1222                         (max_depth < 0 ? "full " :""), name,
1223                         (unsigned long)talloc_total_size(ptr),
1224                         (unsigned long)talloc_total_blocks(ptr));
1225                 return;
1226         }
1227
1228         fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n", 
1229                 depth*4, "",
1230                 name,
1231                 (unsigned long)talloc_total_size(ptr),
1232                 (unsigned long)talloc_total_blocks(ptr),
1233                 (int)talloc_reference_count(ptr), ptr);
1234
1235 #if 0
1236         fprintf(f, "content: ");
1237         if (talloc_total_size(ptr)) {
1238                 int tot = talloc_total_size(ptr);
1239                 int i;
1240
1241                 for (i = 0; i < tot; i++) {
1242                         if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
1243                                 fprintf(f, "%c", ((char *)ptr)[i]);
1244                         } else {
1245                                 fprintf(f, "~%02x", ((char *)ptr)[i]);
1246                         }
1247                 }
1248         }
1249         fprintf(f, "\n");
1250 #endif
1251 }
1252
1253 /*
1254   report on memory usage by all children of a pointer, giving a full tree view
1255 */
1256 void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
1257 {
1258         talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
1259         fflush(f);
1260 }
1261
1262 /*
1263   report on memory usage by all children of a pointer, giving a full tree view
1264 */
1265 void talloc_report_full(const void *ptr, FILE *f)
1266 {
1267         talloc_report_depth_file(ptr, 0, -1, f);
1268 }
1269
1270 /*
1271   report on memory usage by all children of a pointer
1272 */
1273 void talloc_report(const void *ptr, FILE *f)
1274 {
1275         talloc_report_depth_file(ptr, 0, 1, f);
1276 }
1277
1278 /*
1279   report on any memory hanging off the null context
1280 */
1281 static void talloc_report_null(void)
1282 {
1283         if (talloc_total_size(null_context) != 0) {
1284                 talloc_report(null_context, stderr);
1285         }
1286 }
1287
1288 /*
1289   report on any memory hanging off the null context
1290 */
1291 static void talloc_report_null_full(void)
1292 {
1293         if (talloc_total_size(null_context) != 0) {
1294                 talloc_report_full(null_context, stderr);
1295         }
1296 }
1297
1298 /*
1299   enable tracking of the NULL context
1300 */
1301 void talloc_enable_null_tracking(void)
1302 {
1303         if (null_context == NULL) {
1304                 null_context = _talloc_named_const(NULL, 0, "null_context");
1305         }
1306 }
1307
1308 /*
1309   disable tracking of the NULL context
1310 */
1311 void talloc_disable_null_tracking(void)
1312 {
1313         _talloc_free(null_context);
1314         null_context = NULL;
1315 }
1316
1317 /*
1318   enable leak reporting on exit
1319 */
1320 void talloc_enable_leak_report(void)
1321 {
1322         talloc_enable_null_tracking();
1323         atexit(talloc_report_null);
1324 }
1325
1326 /*
1327   enable full leak reporting on exit
1328 */
1329 void talloc_enable_leak_report_full(void)
1330 {
1331         talloc_enable_null_tracking();
1332         atexit(talloc_report_null_full);
1333 }
1334
1335 /* 
1336    talloc and zero memory. 
1337 */
1338 void *_talloc_zero(const void *ctx, size_t size, const char *name)
1339 {
1340         void *p = _talloc_named_const(ctx, size, name);
1341
1342         if (p) {
1343                 memset(p, '\0', size);
1344         }
1345
1346         return p;
1347 }
1348
1349 /*
1350   memdup with a talloc. 
1351 */
1352 void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
1353 {
1354         void *newp = _talloc_named_const(t, size, name);
1355
1356         if (likely(newp)) {
1357                 memcpy(newp, p, size);
1358         }
1359
1360         return newp;
1361 }
1362
1363 static inline char *__talloc_strlendup(const void *t, const char *p, size_t len)
1364 {
1365         char *ret;
1366
1367         ret = (char *)__talloc(t, len + 1);
1368         if (unlikely(!ret)) return NULL;
1369
1370         memcpy(ret, p, len);
1371         ret[len] = 0;
1372
1373         _talloc_set_name_const(ret, ret);
1374         return ret;
1375 }
1376
1377 /*
1378   strdup with a talloc
1379 */
1380 char *talloc_strdup(const void *t, const char *p)
1381 {
1382         if (unlikely(!p)) return NULL;
1383         return __talloc_strlendup(t, p, strlen(p));
1384 }
1385
1386 /*
1387   strndup with a talloc
1388 */
1389 char *talloc_strndup(const void *t, const char *p, size_t n)
1390 {
1391         if (unlikely(!p)) return NULL;
1392         return __talloc_strlendup(t, p, strnlen(p, n));
1393 }
1394
1395 static inline char *__talloc_strlendup_append(char *s, size_t slen,
1396                                               const char *a, size_t alen)
1397 {
1398         char *ret;
1399
1400         ret = talloc_realloc(NULL, s, char, slen + alen + 1);
1401         if (unlikely(!ret)) return NULL;
1402
1403         /* append the string and the trailing \0 */
1404         memcpy(&ret[slen], a, alen);
1405         ret[slen+alen] = 0;
1406
1407         _talloc_set_name_const(ret, ret);
1408         return ret;
1409 }
1410
1411 /*
1412  * Appends at the end of the string.
1413  */
1414 char *talloc_strdup_append(char *s, const char *a)
1415 {
1416         if (unlikely(!s)) {
1417                 return talloc_strdup(NULL, a);
1418         }
1419
1420         if (unlikely(!a)) {
1421                 return s;
1422         }
1423
1424         return __talloc_strlendup_append(s, strlen(s), a, strlen(a));
1425 }
1426
1427 /*
1428  * Appends at the end of the talloc'ed buffer,
1429  * not the end of the string.
1430  */
1431 char *talloc_strdup_append_buffer(char *s, const char *a)
1432 {
1433         size_t slen;
1434
1435         if (unlikely(!s)) {
1436                 return talloc_strdup(NULL, a);
1437         }
1438
1439         if (unlikely(!a)) {
1440                 return s;
1441         }
1442
1443         slen = talloc_get_size(s);
1444         if (likely(slen > 0)) {
1445                 slen--;
1446         }
1447
1448         return __talloc_strlendup_append(s, slen, a, strlen(a));
1449 }
1450
1451 /*
1452  * Appends at the end of the string.
1453  */
1454 char *talloc_strndup_append(char *s, const char *a, size_t n)
1455 {
1456         if (unlikely(!s)) {
1457                 return talloc_strdup(NULL, a);
1458         }
1459
1460         if (unlikely(!a)) {
1461                 return s;
1462         }
1463
1464         return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n));
1465 }
1466
1467 /*
1468  * Appends at the end of the talloc'ed buffer,
1469  * not the end of the string.
1470  */
1471 char *talloc_strndup_append_buffer(char *s, const char *a, size_t n)
1472 {
1473         size_t slen;
1474
1475         if (unlikely(!s)) {
1476                 return talloc_strdup(NULL, a);
1477         }
1478
1479         if (unlikely(!a)) {
1480                 return s;
1481         }
1482
1483         slen = talloc_get_size(s);
1484         if (likely(slen > 0)) {
1485                 slen--;
1486         }
1487
1488         return __talloc_strlendup_append(s, slen, a, strnlen(a, n));
1489 }
1490
1491 #ifndef HAVE_VA_COPY
1492 #ifdef HAVE___VA_COPY
1493 #define va_copy(dest, src) __va_copy(dest, src)
1494 #else
1495 #define va_copy(dest, src) (dest) = (src)
1496 #endif
1497 #endif
1498
1499 char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
1500 {
1501         int len;
1502         char *ret;
1503         va_list ap2;
1504         char c;
1505
1506         /* this call looks strange, but it makes it work on older solaris boxes */
1507         va_copy(ap2, ap);
1508         len = vsnprintf(&c, 1, fmt, ap2);
1509         va_end(ap2);
1510         if (unlikely(len < 0)) {
1511                 return NULL;
1512         }
1513
1514         ret = (char *)__talloc(t, len+1);
1515         if (unlikely(!ret)) return NULL;
1516
1517         va_copy(ap2, ap);
1518         vsnprintf(ret, len+1, fmt, ap2);
1519         va_end(ap2);
1520
1521         _talloc_set_name_const(ret, ret);
1522         return ret;
1523 }
1524
1525
1526 /*
1527   Perform string formatting, and return a pointer to newly allocated
1528   memory holding the result, inside a memory pool.
1529  */
1530 char *talloc_asprintf(const void *t, const char *fmt, ...)
1531 {
1532         va_list ap;
1533         char *ret;
1534
1535         va_start(ap, fmt);
1536         ret = talloc_vasprintf(t, fmt, ap);
1537         va_end(ap);
1538         return ret;
1539 }
1540
1541 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
1542                                                  const char *fmt, va_list ap)
1543                                                  PRINTF_ATTRIBUTE(3,0);
1544
1545 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
1546                                                  const char *fmt, va_list ap)
1547 {
1548         ssize_t alen;
1549         va_list ap2;
1550         char c;
1551
1552         va_copy(ap2, ap);
1553         alen = vsnprintf(&c, 1, fmt, ap2);
1554         va_end(ap2);
1555
1556         if (alen <= 0) {
1557                 /* Either the vsnprintf failed or the format resulted in
1558                  * no characters being formatted. In the former case, we
1559                  * ought to return NULL, in the latter we ought to return
1560                  * the original string. Most current callers of this
1561                  * function expect it to never return NULL.
1562                  */
1563                 return s;
1564         }
1565
1566         s = talloc_realloc(NULL, s, char, slen + alen + 1);
1567         if (!s) return NULL;
1568
1569         va_copy(ap2, ap);
1570         vsnprintf(s + slen, alen + 1, fmt, ap2);
1571         va_end(ap2);
1572
1573         _talloc_set_name_const(s, s);
1574         return s;
1575 }
1576
1577 /**
1578  * Realloc @p s to append the formatted result of @p fmt and @p ap,
1579  * and return @p s, which may have moved.  Good for gradually
1580  * accumulating output into a string buffer. Appends at the end
1581  * of the string.
1582  **/
1583 char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
1584 {
1585         if (unlikely(!s)) {
1586                 return talloc_vasprintf(NULL, fmt, ap);
1587         }
1588
1589         return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap);
1590 }
1591
1592 /**
1593  * Realloc @p s to append the formatted result of @p fmt and @p ap,
1594  * and return @p s, which may have moved. Always appends at the
1595  * end of the talloc'ed buffer, not the end of the string.
1596  **/
1597 char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap)
1598 {
1599         size_t slen;
1600
1601         if (unlikely(!s)) {
1602                 return talloc_vasprintf(NULL, fmt, ap);
1603         }
1604
1605         slen = talloc_get_size(s);
1606         if (likely(slen > 0)) {
1607                 slen--;
1608         }
1609
1610         return __talloc_vaslenprintf_append(s, slen, fmt, ap);
1611 }
1612
1613 /*
1614   Realloc @p s to append the formatted result of @p fmt and return @p
1615   s, which may have moved.  Good for gradually accumulating output
1616   into a string buffer.
1617  */
1618 char *talloc_asprintf_append(char *s, const char *fmt, ...)
1619 {
1620         va_list ap;
1621
1622         va_start(ap, fmt);
1623         s = talloc_vasprintf_append(s, fmt, ap);
1624         va_end(ap);
1625         return s;
1626 }
1627
1628 /*
1629   Realloc @p s to append the formatted result of @p fmt and return @p
1630   s, which may have moved.  Good for gradually accumulating output
1631   into a buffer.
1632  */
1633 char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...)
1634 {
1635         va_list ap;
1636
1637         va_start(ap, fmt);
1638         s = talloc_vasprintf_append_buffer(s, fmt, ap);
1639         va_end(ap);
1640         return s;
1641 }
1642
1643 /*
1644   alloc an array, checking for integer overflow in the array size
1645 */
1646 void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1647 {
1648         if (count >= MAX_TALLOC_SIZE/el_size) {
1649                 return NULL;
1650         }
1651         return _talloc_named_const(ctx, el_size * count, name);
1652 }
1653
1654 /*
1655   alloc an zero array, checking for integer overflow in the array size
1656 */
1657 void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
1658 {
1659         if (count >= MAX_TALLOC_SIZE/el_size) {
1660                 return NULL;
1661         }
1662         return _talloc_zero(ctx, el_size * count, name);
1663 }
1664
1665 /*
1666   realloc an array, checking for integer overflow in the array size
1667 */
1668 void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
1669 {
1670         if (count >= MAX_TALLOC_SIZE/el_size) {
1671                 return NULL;
1672         }
1673         return _talloc_realloc(ctx, ptr, el_size * count, name);
1674 }
1675
1676 /*
1677   a function version of talloc_realloc(), so it can be passed as a function pointer
1678   to libraries that want a realloc function (a realloc function encapsulates
1679   all the basic capabilities of an allocation library, which is why this is useful)
1680 */
1681 void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
1682 {
1683         return _talloc_realloc(context, ptr, size, NULL);
1684 }
1685
1686
1687 static int talloc_autofree_destructor(void *ptr)
1688 {
1689         autofree_context = NULL;
1690         return 0;
1691 }
1692
1693 static void talloc_autofree(void)
1694 {
1695         _talloc_free(autofree_context);
1696 }
1697
1698 /*
1699   return a context which will be auto-freed on exit
1700   this is useful for reducing the noise in leak reports
1701 */
1702 void *talloc_autofree_context(void)
1703 {
1704         if (autofree_context == NULL) {
1705                 autofree_context = _talloc_named_const(NULL, 0, "autofree_context");
1706                 talloc_set_destructor(autofree_context, talloc_autofree_destructor);
1707                 atexit(talloc_autofree);
1708         }
1709         return autofree_context;
1710 }
1711
1712 size_t talloc_get_size(const void *context)
1713 {
1714         struct talloc_chunk *tc;
1715
1716         if (context == NULL)
1717                 return 0;
1718
1719         tc = talloc_chunk_from_ptr(context);
1720
1721         return tc->size;
1722 }
1723
1724 /*
1725   find a parent of this context that has the given name, if any
1726 */
1727 void *talloc_find_parent_byname(const void *context, const char *name)
1728 {
1729         struct talloc_chunk *tc;
1730
1731         if (context == NULL) {
1732                 return NULL;
1733         }
1734
1735         tc = talloc_chunk_from_ptr(context);
1736         while (tc) {
1737                 if (tc->name && strcmp(tc->name, name) == 0) {
1738                         return TC_PTR_FROM_CHUNK(tc);
1739                 }
1740                 while (tc && tc->prev) tc = tc->prev;
1741                 if (tc) {
1742                         tc = tc->parent;
1743                 }
1744         }
1745         return NULL;
1746 }
1747
1748 /*
1749   show the parentage of a context
1750 */
1751 void talloc_show_parents(const void *context, FILE *file)
1752 {
1753         struct talloc_chunk *tc;
1754
1755         if (context == NULL) {
1756                 fprintf(file, "talloc no parents for NULL\n");
1757                 return;
1758         }
1759
1760         tc = talloc_chunk_from_ptr(context);
1761         fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
1762         while (tc) {
1763                 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
1764                 while (tc && tc->prev) tc = tc->prev;
1765                 if (tc) {
1766                         tc = tc->parent;
1767                 }
1768         }
1769         fflush(file);
1770 }
1771
1772 /*
1773   return 1 if ptr is a parent of context
1774 */
1775 int talloc_is_parent(const void *context, const void *ptr)
1776 {
1777         struct talloc_chunk *tc;
1778
1779         if (context == NULL) {
1780                 return 0;
1781         }
1782
1783         tc = talloc_chunk_from_ptr(context);
1784         while (tc) {
1785                 if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
1786                 while (tc && tc->prev) tc = tc->prev;
1787                 if (tc) {
1788                         tc = tc->parent;
1789                 }
1790         }
1791         return 0;
1792 }