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