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