talloc: use TC_UNDEFINE_SHRINK_CHUNK() instead of TC_INVALIDATE_SHRINK_CHUNK() for...
[bbaumbach/samba-autobuild/.git] / lib / talloc / talloc.c
1 /* 
2    Samba Unix SMB/CIFS implementation.
3
4    Samba trivial allocation library - new interface
5
6    NOTE: Please read talloc_guide.txt for full documentation
7
8    Copyright (C) Andrew Tridgell 2004
9    Copyright (C) Stefan Metzmacher 2006
10    
11      ** NOTE! The following LGPL license applies to the talloc
12      ** library. This does NOT imply that all of Samba is released
13      ** under the LGPL
14    
15    This library is free software; you can redistribute it and/or
16    modify it under the terms of the GNU Lesser General Public
17    License as published by the Free Software Foundation; either
18    version 3 of the License, or (at your option) any later version.
19
20    This library is distributed in the hope that it will be useful,
21    but WITHOUT ANY WARRANTY; without even the implied warranty of
22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23    Lesser General Public License for more details.
24
25    You should have received a copy of the GNU Lesser General Public
26    License along with this library; if not, see <http://www.gnu.org/licenses/>.
27 */
28
29 /*
30   inspired by http://swapped.cc/halloc/
31 */
32
33 #include "replace.h"
34 #include "talloc.h"
35
36 #ifdef TALLOC_BUILD_VERSION_MAJOR
37 #if (TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR)
38 #error "TALLOC_VERSION_MAJOR != TALLOC_BUILD_VERSION_MAJOR"
39 #endif
40 #endif
41
42 #ifdef TALLOC_BUILD_VERSION_MINOR
43 #if (TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR)
44 #error "TALLOC_VERSION_MINOR != TALLOC_BUILD_VERSION_MINOR"
45 #endif
46 #endif
47
48 /* Special macros that are no-ops except when run under Valgrind on
49  * x86.  They've moved a little bit from valgrind 1.0.4 to 1.9.4 */
50 #ifdef HAVE_VALGRIND_MEMCHECK_H
51         /* memcheck.h includes valgrind.h */
52 #include <valgrind/memcheck.h>
53 #elif defined(HAVE_VALGRIND_H)
54 #include <valgrind.h>
55 #endif
56
57 /* use this to force every realloc to change the pointer, to stress test
58    code that might not cope */
59 #define ALWAYS_REALLOC 0
60
61
62 #define MAX_TALLOC_SIZE 0x10000000
63 #define TALLOC_MAGIC_BASE 0xe814ec70
64 #define TALLOC_MAGIC ( \
65         TALLOC_MAGIC_BASE + \
66         (TALLOC_VERSION_MAJOR << 12) + \
67         (TALLOC_VERSION_MINOR << 4) \
68 )
69
70 #define TALLOC_FLAG_FREE 0x01
71 #define TALLOC_FLAG_LOOP 0x02
72 #define TALLOC_FLAG_POOL 0x04           /* This is a talloc pool */
73 #define TALLOC_FLAG_POOLMEM 0x08        /* This is allocated in a pool */
74 #define TALLOC_MAGIC_REFERENCE ((const char *)1)
75
76 /* by default we abort when given a bad pointer (such as when talloc_free() is called 
77    on a pointer that came from malloc() */
78 #ifndef TALLOC_ABORT
79 #define TALLOC_ABORT(reason) abort()
80 #endif
81
82 #ifndef discard_const_p
83 #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
84 # define discard_const_p(type, ptr) ((type *)((intptr_t)(ptr)))
85 #else
86 # define discard_const_p(type, ptr) ((type *)(ptr))
87 #endif
88 #endif
89
90 /* these macros gain us a few percent of speed on gcc */
91 #if (__GNUC__ >= 3)
92 /* the strange !! is to ensure that __builtin_expect() takes either 0 or 1
93    as its first argument */
94 #ifndef likely
95 #define likely(x)   __builtin_expect(!!(x), 1)
96 #endif
97 #ifndef unlikely
98 #define unlikely(x) __builtin_expect(!!(x), 0)
99 #endif
100 #else
101 #ifndef likely
102 #define likely(x) (x)
103 #endif
104 #ifndef unlikely
105 #define unlikely(x) (x)
106 #endif
107 #endif
108
109 /* this null_context is only used if talloc_enable_leak_report() or
110    talloc_enable_leak_report_full() is called, otherwise it remains
111    NULL
112 */
113 static void *null_context;
114 static void *autofree_context;
115
116 /* used to enable fill of memory on free, which can be useful for
117  * catching use after free errors when valgrind is too slow
118  */
119 static struct {
120         bool initialised;
121         bool enabled;
122         uint8_t fill_value;
123 } talloc_fill;
124
125 #define TALLOC_FILL_ENV "TALLOC_FREE_FILL"
126
127 /*
128  * do not wipe the header, to allow the
129  * double-free logic to still work
130  */
131 #define TC_INVALIDATE_FULL_FILL_CHUNK(_tc) do { \
132         if (unlikely(talloc_fill.enabled)) { \
133                 size_t _flen = (_tc)->size; \
134                 char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \
135                 memset(_fptr, talloc_fill.fill_value, _flen); \
136         } \
137 } while (0)
138
139 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
140 /* Mark the whole chunk as not accessable */
141 #define TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc) do { \
142         size_t _flen = TC_HDR_SIZE + (_tc)->size; \
143         char *_fptr = (char *)(_tc); \
144         VALGRIND_MAKE_MEM_NOACCESS(_fptr, _flen); \
145 } while(0)
146 #else
147 #define TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc) do { } while (0)
148 #endif
149
150 #define TC_INVALIDATE_FULL_CHUNK(_tc) do { \
151         TC_INVALIDATE_FULL_FILL_CHUNK(_tc); \
152         TC_INVALIDATE_FULL_VALGRIND_CHUNK(_tc); \
153 } while (0)
154
155 #define TC_INVALIDATE_SHRINK_FILL_CHUNK(_tc, _new_size) do { \
156         if (unlikely(talloc_fill.enabled)) { \
157                 size_t _flen = (_tc)->size - (_new_size); \
158                 char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \
159                 _fptr += (_new_size); \
160                 memset(_fptr, talloc_fill.fill_value, _flen); \
161         } \
162 } while (0)
163
164 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
165 /* Mark the unused bytes not accessable */
166 #define TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { \
167         size_t _flen = (_tc)->size - (_new_size); \
168         char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \
169         _fptr += (_new_size); \
170         VALGRIND_MAKE_MEM_NOACCESS(_fptr, _flen); \
171 } while (0)
172 #else
173 #define TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { } while (0)
174 #endif
175
176 #define TC_INVALIDATE_SHRINK_CHUNK(_tc, _new_size) do { \
177         TC_INVALIDATE_SHRINK_FILL_CHUNK(_tc, _new_size); \
178         TC_INVALIDATE_SHRINK_VALGRIND_CHUNK(_tc, _new_size); \
179 } while (0)
180
181 #define TC_UNDEFINE_SHRINK_FILL_CHUNK(_tc, _new_size) do { \
182         if (unlikely(talloc_fill.enabled)) { \
183                 size_t _flen = (_tc)->size - (_new_size); \
184                 char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \
185                 _fptr += (_new_size); \
186                 memset(_fptr, talloc_fill.fill_value, _flen); \
187         } \
188 } while (0)
189
190 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
191 /* Mark the unused bytes as undefined */
192 #define TC_UNDEFINE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { \
193         size_t _flen = (_tc)->size - (_new_size); \
194         char *_fptr = (char *)TC_PTR_FROM_CHUNK(_tc); \
195         _fptr += (_new_size); \
196         VALGRIND_MAKE_MEM_UNDEFINED(_fptr, _flen); \
197 } while (0)
198 #else
199 #define TC_UNDEFINE_SHRINK_VALGRIND_CHUNK(_tc, _new_size) do { } while (0)
200 #endif
201
202 #define TC_UNDEFINE_SHRINK_CHUNK(_tc, _new_size) do { \
203         TC_UNDEFINE_SHRINK_FILL_CHUNK(_tc, _new_size); \
204         TC_UNDEFINE_SHRINK_VALGRIND_CHUNK(_tc, _new_size); \
205 } while (0)
206
207 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
208 /* Mark the new bytes as undefined */
209 #define TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size) do { \
210         size_t _old_used = TC_HDR_SIZE + (_tc)->size; \
211         size_t _new_used = TC_HDR_SIZE + (_new_size); \
212         size_t _flen = _new_used - _old_used; \
213         char *_fptr = _old_used + (char *)(_tc); \
214         VALGRIND_MAKE_MEM_UNDEFINED(_fptr, _flen); \
215 } while (0)
216 #else
217 #define TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size) do { } while (0)
218 #endif
219
220 #define TC_UNDEFINE_GROW_CHUNK(_tc, _new_size) do { \
221         TC_UNDEFINE_GROW_VALGRIND_CHUNK(_tc, _new_size); \
222 } while (0)
223
224 struct talloc_reference_handle {
225         struct talloc_reference_handle *next, *prev;
226         void *ptr;
227         const char *location;
228 };
229
230 typedef int (*talloc_destructor_t)(void *);
231
232 struct talloc_chunk {
233         struct talloc_chunk *next, *prev;
234         struct talloc_chunk *parent, *child;
235         struct talloc_reference_handle *refs;
236         talloc_destructor_t destructor;
237         const char *name;
238         size_t size;
239         unsigned flags;
240
241         /*
242          * "pool" has dual use:
243          *
244          * For the talloc pool itself (i.e. TALLOC_FLAG_POOL is set), "pool"
245          * marks the end of the currently allocated area.
246          *
247          * For members of the pool (i.e. TALLOC_FLAG_POOLMEM is set), "pool"
248          * is a pointer to the struct talloc_chunk of the pool that it was
249          * allocated from. This way children can quickly find the pool to chew
250          * from.
251          */
252         void *pool;
253 };
254
255 /* 16 byte alignment seems to keep everyone happy */
256 #define TC_ALIGN16(s) (((s)+15)&~15)
257 #define TC_HDR_SIZE TC_ALIGN16(sizeof(struct talloc_chunk))
258 #define TC_PTR_FROM_CHUNK(tc) ((void *)(TC_HDR_SIZE + (char*)tc))
259
260 _PUBLIC_ int talloc_version_major(void)
261 {
262         return TALLOC_VERSION_MAJOR;
263 }
264
265 _PUBLIC_ int talloc_version_minor(void)
266 {
267         return TALLOC_VERSION_MINOR;
268 }
269
270 static void (*talloc_log_fn)(const char *message);
271
272 _PUBLIC_ void talloc_set_log_fn(void (*log_fn)(const char *message))
273 {
274         talloc_log_fn = log_fn;
275 }
276
277 static void talloc_log(const char *fmt, ...) PRINTF_ATTRIBUTE(1,2);
278 static void talloc_log(const char *fmt, ...)
279 {
280         va_list ap;
281         char *message;
282
283         if (!talloc_log_fn) {
284                 return;
285         }
286
287         va_start(ap, fmt);
288         message = talloc_vasprintf(NULL, fmt, ap);
289         va_end(ap);
290
291         talloc_log_fn(message);
292         talloc_free(message);
293 }
294
295 static void talloc_log_stderr(const char *message)
296 {
297         fprintf(stderr, "%s", message);
298 }
299
300 _PUBLIC_ void talloc_set_log_stderr(void)
301 {
302         talloc_set_log_fn(talloc_log_stderr);
303 }
304
305 static void (*talloc_abort_fn)(const char *reason);
306
307 _PUBLIC_ void talloc_set_abort_fn(void (*abort_fn)(const char *reason))
308 {
309         talloc_abort_fn = abort_fn;
310 }
311
312 static void talloc_abort(const char *reason)
313 {
314         talloc_log("%s\n", reason);
315
316         if (!talloc_abort_fn) {
317                 TALLOC_ABORT(reason);
318         }
319
320         talloc_abort_fn(reason);
321 }
322
323 static void talloc_abort_magic(unsigned magic)
324 {
325         unsigned striped = magic - TALLOC_MAGIC_BASE;
326         unsigned major = (striped & 0xFFFFF000) >> 12;
327         unsigned minor = (striped & 0x00000FF0) >> 4;
328         talloc_log("Bad talloc magic[0x%08X/%u/%u] expected[0x%08X/%u/%u]\n",
329                    magic, major, minor,
330                    TALLOC_MAGIC, TALLOC_VERSION_MAJOR, TALLOC_VERSION_MINOR);
331         talloc_abort("Bad talloc magic value - wrong talloc version used/mixed");
332 }
333
334 static void talloc_abort_access_after_free(void)
335 {
336         talloc_abort("Bad talloc magic value - access after free");
337 }
338
339 static void talloc_abort_unknown_value(void)
340 {
341         talloc_abort("Bad talloc magic value - unknown value");
342 }
343
344 /* panic if we get a bad magic value */
345 static inline struct talloc_chunk *talloc_chunk_from_ptr(const void *ptr)
346 {
347         const char *pp = (const char *)ptr;
348         struct talloc_chunk *tc = discard_const_p(struct talloc_chunk, pp - TC_HDR_SIZE);
349         if (unlikely((tc->flags & (TALLOC_FLAG_FREE | ~0xF)) != TALLOC_MAGIC)) { 
350                 if ((tc->flags & (~0xFFF)) == TALLOC_MAGIC_BASE) {
351                         talloc_abort_magic(tc->flags & (~0xF));
352                         return NULL;
353                 }
354
355                 if (tc->flags & TALLOC_FLAG_FREE) {
356                         talloc_log("talloc: access after free error - first free may be at %s\n", tc->name);
357                         talloc_abort_access_after_free();
358                         return NULL;
359                 } else {
360                         talloc_abort_unknown_value();
361                         return NULL;
362                 }
363         }
364         return tc;
365 }
366
367 /* hook into the front of the list */
368 #define _TLIST_ADD(list, p) \
369 do { \
370         if (!(list)) { \
371                 (list) = (p); \
372                 (p)->next = (p)->prev = NULL; \
373         } else { \
374                 (list)->prev = (p); \
375                 (p)->next = (list); \
376                 (p)->prev = NULL; \
377                 (list) = (p); \
378         }\
379 } while (0)
380
381 /* remove an element from a list - element doesn't have to be in list. */
382 #define _TLIST_REMOVE(list, p) \
383 do { \
384         if ((p) == (list)) { \
385                 (list) = (p)->next; \
386                 if (list) (list)->prev = NULL; \
387         } else { \
388                 if ((p)->prev) (p)->prev->next = (p)->next; \
389                 if ((p)->next) (p)->next->prev = (p)->prev; \
390         } \
391         if ((p) && ((p) != (list))) (p)->next = (p)->prev = NULL; \
392 } while (0)
393
394
395 /*
396   return the parent chunk of a pointer
397 */
398 static inline struct talloc_chunk *talloc_parent_chunk(const void *ptr)
399 {
400         struct talloc_chunk *tc;
401
402         if (unlikely(ptr == NULL)) {
403                 return NULL;
404         }
405
406         tc = talloc_chunk_from_ptr(ptr);
407         while (tc->prev) tc=tc->prev;
408
409         return tc->parent;
410 }
411
412 _PUBLIC_ void *talloc_parent(const void *ptr)
413 {
414         struct talloc_chunk *tc = talloc_parent_chunk(ptr);
415         return tc? TC_PTR_FROM_CHUNK(tc) : NULL;
416 }
417
418 /*
419   find parents name
420 */
421 _PUBLIC_ const char *talloc_parent_name(const void *ptr)
422 {
423         struct talloc_chunk *tc = talloc_parent_chunk(ptr);
424         return tc? tc->name : NULL;
425 }
426
427 /*
428   A pool carries an in-pool object count count in the first 16 bytes.
429   bytes. This is done to support talloc_steal() to a parent outside of the
430   pool. The count includes the pool itself, so a talloc_free() on a pool will
431   only destroy the pool if the count has dropped to zero. A talloc_free() of a
432   pool member will reduce the count, and eventually also call free(3) on the
433   pool memory.
434
435   The object count is not put into "struct talloc_chunk" because it is only
436   relevant for talloc pools and the alignment to 16 bytes would increase the
437   memory footprint of each talloc chunk by those 16 bytes.
438 */
439
440 #define TALLOC_POOL_HDR_SIZE 16
441
442 #define TC_POOL_SPACE_LEFT(_pool_tc) \
443         PTR_DIFF(TC_HDR_SIZE + (_pool_tc)->size + (char *)(_pool_tc), \
444                  (_pool_tc)->pool)
445
446 #define TC_POOL_FIRST_CHUNK(_pool_tc) \
447         ((void *)(TC_HDR_SIZE + TALLOC_POOL_HDR_SIZE + (char *)(_pool_tc)))
448
449 #define TC_POOLMEM_CHUNK_SIZE(_tc) \
450         TC_ALIGN16(TC_HDR_SIZE + (_tc)->size)
451
452 #define TC_POOLMEM_NEXT_CHUNK(_tc) \
453         ((void *)(TC_POOLMEM_CHUNK_SIZE(tc) + (char*)(_tc)))
454
455 /* Mark the whole remaining pool as not accessable */
456 #define TC_INVALIDATE_FILL_POOL(_pool_tc) do { \
457         if (unlikely(talloc_fill.enabled)) { \
458                 size_t _flen = TC_POOL_SPACE_LEFT(_pool_tc); \
459                 char *_fptr = (char *)(_pool_tc)->pool; \
460                 memset(_fptr, talloc_fill.fill_value, _flen); \
461         } \
462 } while(0)
463
464 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_NOACCESS)
465 /* Mark the whole remaining pool as not accessable */
466 #define TC_INVALIDATE_VALGRIND_POOL(_pool_tc) do { \
467         size_t _flen = TC_POOL_SPACE_LEFT(_pool_tc); \
468         char *_fptr = (char *)(_pool_tc)->pool; \
469         VALGRIND_MAKE_MEM_NOACCESS(_fptr, _flen); \
470 } while(0)
471 #else
472 #define TC_INVALIDATE_VALGRIND_POOL(_pool_tc) do { } while (0)
473 #endif
474
475 #define TC_INVALIDATE_POOL(_pool_tc) do { \
476         TC_INVALIDATE_FILL_POOL(_pool_tc); \
477         TC_INVALIDATE_VALGRIND_POOL(_pool_tc); \
478 } while (0)
479
480 static unsigned int *talloc_pool_objectcount(struct talloc_chunk *tc)
481 {
482         return (unsigned int *)((char *)tc + TC_HDR_SIZE);
483 }
484
485 /*
486   Allocate from a pool
487 */
488
489 static struct talloc_chunk *talloc_alloc_pool(struct talloc_chunk *parent,
490                                               size_t size)
491 {
492         struct talloc_chunk *pool_ctx = NULL;
493         size_t space_left;
494         struct talloc_chunk *result;
495         size_t chunk_size;
496
497         if (parent == NULL) {
498                 return NULL;
499         }
500
501         if (parent->flags & TALLOC_FLAG_POOL) {
502                 pool_ctx = parent;
503         }
504         else if (parent->flags & TALLOC_FLAG_POOLMEM) {
505                 pool_ctx = (struct talloc_chunk *)parent->pool;
506         }
507
508         if (pool_ctx == NULL) {
509                 return NULL;
510         }
511
512         space_left = TC_POOL_SPACE_LEFT(pool_ctx);
513
514         /*
515          * Align size to 16 bytes
516          */
517         chunk_size = TC_ALIGN16(size);
518
519         if (space_left < chunk_size) {
520                 return NULL;
521         }
522
523         result = (struct talloc_chunk *)pool_ctx->pool;
524
525 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
526         VALGRIND_MAKE_MEM_UNDEFINED(result, size);
527 #endif
528
529         pool_ctx->pool = (void *)((char *)result + chunk_size);
530
531         result->flags = TALLOC_MAGIC | TALLOC_FLAG_POOLMEM;
532         result->pool = pool_ctx;
533
534         *talloc_pool_objectcount(pool_ctx) += 1;
535
536         return result;
537 }
538
539 /* 
540    Allocate a bit of memory as a child of an existing pointer
541 */
542 static inline void *__talloc(const void *context, size_t size)
543 {
544         struct talloc_chunk *tc = NULL;
545
546         if (unlikely(context == NULL)) {
547                 context = null_context;
548         }
549
550         if (unlikely(size >= MAX_TALLOC_SIZE)) {
551                 return NULL;
552         }
553
554         if (context != NULL) {
555                 tc = talloc_alloc_pool(talloc_chunk_from_ptr(context),
556                                        TC_HDR_SIZE+size);
557         }
558
559         if (tc == NULL) {
560                 tc = (struct talloc_chunk *)malloc(TC_HDR_SIZE+size);
561                 if (unlikely(tc == NULL)) return NULL;
562                 tc->flags = TALLOC_MAGIC;
563                 tc->pool  = NULL;
564         }
565
566         tc->size = size;
567         tc->destructor = NULL;
568         tc->child = NULL;
569         tc->name = NULL;
570         tc->refs = NULL;
571
572         if (likely(context)) {
573                 struct talloc_chunk *parent = talloc_chunk_from_ptr(context);
574
575                 if (parent->child) {
576                         parent->child->parent = NULL;
577                         tc->next = parent->child;
578                         tc->next->prev = tc;
579                 } else {
580                         tc->next = NULL;
581                 }
582                 tc->parent = parent;
583                 tc->prev = NULL;
584                 parent->child = tc;
585         } else {
586                 tc->next = tc->prev = tc->parent = NULL;
587         }
588
589         return TC_PTR_FROM_CHUNK(tc);
590 }
591
592 /*
593  * Create a talloc pool
594  */
595
596 _PUBLIC_ void *talloc_pool(const void *context, size_t size)
597 {
598         void *result = __talloc(context, size + TALLOC_POOL_HDR_SIZE);
599         struct talloc_chunk *tc;
600
601         if (unlikely(result == NULL)) {
602                 return NULL;
603         }
604
605         tc = talloc_chunk_from_ptr(result);
606
607         tc->flags |= TALLOC_FLAG_POOL;
608         tc->pool = TC_POOL_FIRST_CHUNK(tc);
609
610         *talloc_pool_objectcount(tc) = 1;
611
612         TC_INVALIDATE_POOL(tc);
613
614         return result;
615 }
616
617 /*
618   setup a destructor to be called on free of a pointer
619   the destructor should return 0 on success, or -1 on failure.
620   if the destructor fails then the free is failed, and the memory can
621   be continued to be used
622 */
623 _PUBLIC_ void _talloc_set_destructor(const void *ptr, int (*destructor)(void *))
624 {
625         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
626         tc->destructor = destructor;
627 }
628
629 /*
630   increase the reference count on a piece of memory. 
631 */
632 _PUBLIC_ int talloc_increase_ref_count(const void *ptr)
633 {
634         if (unlikely(!talloc_reference(null_context, ptr))) {
635                 return -1;
636         }
637         return 0;
638 }
639
640 /*
641   helper for talloc_reference()
642
643   this is referenced by a function pointer and should not be inline
644 */
645 static int talloc_reference_destructor(struct talloc_reference_handle *handle)
646 {
647         struct talloc_chunk *ptr_tc = talloc_chunk_from_ptr(handle->ptr);
648         _TLIST_REMOVE(ptr_tc->refs, handle);
649         return 0;
650 }
651
652 /*
653    more efficient way to add a name to a pointer - the name must point to a 
654    true string constant
655 */
656 static inline void _talloc_set_name_const(const void *ptr, const char *name)
657 {
658         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
659         tc->name = name;
660 }
661
662 /*
663   internal talloc_named_const()
664 */
665 static inline void *_talloc_named_const(const void *context, size_t size, const char *name)
666 {
667         void *ptr;
668
669         ptr = __talloc(context, size);
670         if (unlikely(ptr == NULL)) {
671                 return NULL;
672         }
673
674         _talloc_set_name_const(ptr, name);
675
676         return ptr;
677 }
678
679 /*
680   make a secondary reference to a pointer, hanging off the given context.
681   the pointer remains valid until both the original caller and this given
682   context are freed.
683   
684   the major use for this is when two different structures need to reference the 
685   same underlying data, and you want to be able to free the two instances separately,
686   and in either order
687 */
688 _PUBLIC_ void *_talloc_reference_loc(const void *context, const void *ptr, const char *location)
689 {
690         struct talloc_chunk *tc;
691         struct talloc_reference_handle *handle;
692         if (unlikely(ptr == NULL)) return NULL;
693
694         tc = talloc_chunk_from_ptr(ptr);
695         handle = (struct talloc_reference_handle *)_talloc_named_const(context,
696                                                    sizeof(struct talloc_reference_handle),
697                                                    TALLOC_MAGIC_REFERENCE);
698         if (unlikely(handle == NULL)) return NULL;
699
700         /* note that we hang the destructor off the handle, not the
701            main context as that allows the caller to still setup their
702            own destructor on the context if they want to */
703         talloc_set_destructor(handle, talloc_reference_destructor);
704         handle->ptr = discard_const_p(void, ptr);
705         handle->location = location;
706         _TLIST_ADD(tc->refs, handle);
707         return handle->ptr;
708 }
709
710 static void *_talloc_steal_internal(const void *new_ctx, const void *ptr);
711
712 /* 
713    internal talloc_free call
714 */
715 static inline int _talloc_free_internal(void *ptr, const char *location)
716 {
717         struct talloc_chunk *tc;
718
719         if (unlikely(ptr == NULL)) {
720                 return -1;
721         }
722
723         /* possibly initialised the talloc fill value */
724         if (unlikely(!talloc_fill.initialised)) {
725                 const char *fill = getenv(TALLOC_FILL_ENV);
726                 if (fill != NULL) {
727                         talloc_fill.enabled = true;
728                         talloc_fill.fill_value = strtoul(fill, NULL, 0);
729                 }
730                 talloc_fill.initialised = true;
731         }
732
733         tc = talloc_chunk_from_ptr(ptr);
734
735         if (unlikely(tc->refs)) {
736                 int is_child;
737                 /* check if this is a reference from a child or
738                  * grandchild back to it's parent or grandparent
739                  *
740                  * in that case we need to remove the reference and
741                  * call another instance of talloc_free() on the current
742                  * pointer.
743                  */
744                 is_child = talloc_is_parent(tc->refs, ptr);
745                 _talloc_free_internal(tc->refs, location);
746                 if (is_child) {
747                         return _talloc_free_internal(ptr, location);
748                 }
749                 return -1;
750         }
751
752         if (unlikely(tc->flags & TALLOC_FLAG_LOOP)) {
753                 /* we have a free loop - stop looping */
754                 return 0;
755         }
756
757         if (unlikely(tc->destructor)) {
758                 talloc_destructor_t d = tc->destructor;
759                 if (d == (talloc_destructor_t)-1) {
760                         return -1;
761                 }
762                 tc->destructor = (talloc_destructor_t)-1;
763                 if (d(ptr) == -1) {
764                         tc->destructor = d;
765                         return -1;
766                 }
767                 tc->destructor = NULL;
768         }
769
770         if (tc->parent) {
771                 _TLIST_REMOVE(tc->parent->child, tc);
772                 if (tc->parent->child) {
773                         tc->parent->child->parent = tc->parent;
774                 }
775         } else {
776                 if (tc->prev) tc->prev->next = tc->next;
777                 if (tc->next) tc->next->prev = tc->prev;
778         }
779
780         tc->flags |= TALLOC_FLAG_LOOP;
781
782         while (tc->child) {
783                 /* we need to work out who will own an abandoned child
784                    if it cannot be freed. In priority order, the first
785                    choice is owner of any remaining reference to this
786                    pointer, the second choice is our parent, and the
787                    final choice is the null context. */
788                 void *child = TC_PTR_FROM_CHUNK(tc->child);
789                 const void *new_parent = null_context;
790                 struct talloc_chunk *old_parent = NULL;
791                 if (unlikely(tc->child->refs)) {
792                         struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
793                         if (p) new_parent = TC_PTR_FROM_CHUNK(p);
794                 }
795                 /* finding the parent here is potentially quite
796                    expensive, but the alternative, which is to change
797                    talloc to always have a valid tc->parent pointer,
798                    makes realloc more expensive where there are a
799                    large number of children.
800
801                    The reason we need the parent pointer here is that
802                    if _talloc_free_internal() fails due to references
803                    or a failing destructor we need to re-parent, but
804                    the free call can invalidate the prev pointer.
805                 */
806                 if (new_parent == null_context && (tc->child->refs || tc->child->destructor)) {
807                         old_parent = talloc_parent_chunk(ptr);
808                 }
809                 if (unlikely(_talloc_free_internal(child, location) == -1)) {
810                         if (new_parent == null_context) {
811                                 struct talloc_chunk *p = old_parent;
812                                 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
813                         }
814                         _talloc_steal_internal(new_parent, child);
815                 }
816         }
817
818         tc->flags |= TALLOC_FLAG_FREE;
819
820         /* we mark the freed memory with where we called the free
821          * from. This means on a double free error we can report where
822          * the first free came from 
823          */      
824         tc->name = location;
825
826         if (tc->flags & (TALLOC_FLAG_POOL|TALLOC_FLAG_POOLMEM)) {
827                 struct talloc_chunk *pool;
828                 void *next_tc = NULL;
829                 unsigned int *pool_object_count;
830
831                 if (unlikely(tc->flags & TALLOC_FLAG_POOL)) {
832                         pool = tc;
833                 } else {
834                         pool = (struct talloc_chunk *)tc->pool;
835                         next_tc = TC_POOLMEM_NEXT_CHUNK(tc);
836
837                         TC_INVALIDATE_FULL_CHUNK(tc);
838                 }
839
840                 pool_object_count = talloc_pool_objectcount(pool);
841
842                 if (unlikely(*pool_object_count == 0)) {
843                         talloc_abort("Pool object count zero!");
844                         return 0;
845                 }
846
847                 *pool_object_count -= 1;
848
849                 if (unlikely(*pool_object_count == 1)) {
850                         /*
851                          * if there is just object left in the pool
852                          * it means this is the pool itself and
853                          * the rest is available for new objects
854                          * again.
855                          */
856                         pool->pool = TC_POOL_FIRST_CHUNK(pool);
857                         TC_INVALIDATE_POOL(pool);
858                 } else if (unlikely(*pool_object_count == 0)) {
859                         TC_INVALIDATE_FULL_CHUNK(pool);
860                         free(pool);
861                 } else if (pool->pool == next_tc) {
862                         /*
863                          * if pool->pool still points to end of
864                          * 'tc' (which is stored in the 'next_tc' variable),
865                          * we can reclaim the memory of 'tc'.
866                          */
867                         pool->pool = tc;
868                 }
869         } else {
870                 TC_INVALIDATE_FULL_CHUNK(tc);
871                 free(tc);
872         }
873         return 0;
874 }
875
876 /* 
877    move a lump of memory from one talloc context to another return the
878    ptr on success, or NULL if it could not be transferred.
879    passing NULL as ptr will always return NULL with no side effects.
880 */
881 static void *_talloc_steal_internal(const void *new_ctx, const void *ptr)
882 {
883         struct talloc_chunk *tc, *new_tc;
884
885         if (unlikely(!ptr)) {
886                 return NULL;
887         }
888
889         if (unlikely(new_ctx == NULL)) {
890                 new_ctx = null_context;
891         }
892
893         tc = talloc_chunk_from_ptr(ptr);
894
895         if (unlikely(new_ctx == NULL)) {
896                 if (tc->parent) {
897                         _TLIST_REMOVE(tc->parent->child, tc);
898                         if (tc->parent->child) {
899                                 tc->parent->child->parent = tc->parent;
900                         }
901                 } else {
902                         if (tc->prev) tc->prev->next = tc->next;
903                         if (tc->next) tc->next->prev = tc->prev;
904                 }
905                 
906                 tc->parent = tc->next = tc->prev = NULL;
907                 return discard_const_p(void, ptr);
908         }
909
910         new_tc = talloc_chunk_from_ptr(new_ctx);
911
912         if (unlikely(tc == new_tc || tc->parent == new_tc)) {
913                 return discard_const_p(void, ptr);
914         }
915
916         if (tc->parent) {
917                 _TLIST_REMOVE(tc->parent->child, tc);
918                 if (tc->parent->child) {
919                         tc->parent->child->parent = tc->parent;
920                 }
921         } else {
922                 if (tc->prev) tc->prev->next = tc->next;
923                 if (tc->next) tc->next->prev = tc->prev;
924         }
925
926         tc->parent = new_tc;
927         if (new_tc->child) new_tc->child->parent = NULL;
928         _TLIST_ADD(new_tc->child, tc);
929
930         return discard_const_p(void, ptr);
931 }
932
933 /* 
934    move a lump of memory from one talloc context to another return the
935    ptr on success, or NULL if it could not be transferred.
936    passing NULL as ptr will always return NULL with no side effects.
937 */
938 _PUBLIC_ void *_talloc_steal_loc(const void *new_ctx, const void *ptr, const char *location)
939 {
940         struct talloc_chunk *tc;
941
942         if (unlikely(ptr == NULL)) {
943                 return NULL;
944         }
945         
946         tc = talloc_chunk_from_ptr(ptr);
947         
948         if (unlikely(tc->refs != NULL) && talloc_parent(ptr) != new_ctx) {
949                 struct talloc_reference_handle *h;
950
951                 talloc_log("WARNING: talloc_steal with references at %s\n",
952                            location);
953
954                 for (h=tc->refs; h; h=h->next) {
955                         talloc_log("\treference at %s\n",
956                                    h->location);
957                 }
958         }
959
960 #if 0
961         /* this test is probably too expensive to have on in the
962            normal build, but it useful for debugging */
963         if (talloc_is_parent(new_ctx, ptr)) {
964                 talloc_log("WARNING: stealing into talloc child at %s\n", location);
965         }
966 #endif
967         
968         return _talloc_steal_internal(new_ctx, ptr);
969 }
970
971 /* 
972    this is like a talloc_steal(), but you must supply the old
973    parent. This resolves the ambiguity in a talloc_steal() which is
974    called on a context that has more than one parent (via references)
975
976    The old parent can be either a reference or a parent
977 */
978 _PUBLIC_ void *talloc_reparent(const void *old_parent, const void *new_parent, const void *ptr)
979 {
980         struct talloc_chunk *tc;
981         struct talloc_reference_handle *h;
982
983         if (unlikely(ptr == NULL)) {
984                 return NULL;
985         }
986
987         if (old_parent == talloc_parent(ptr)) {
988                 return _talloc_steal_internal(new_parent, ptr);
989         }
990
991         tc = talloc_chunk_from_ptr(ptr);
992         for (h=tc->refs;h;h=h->next) {
993                 if (talloc_parent(h) == old_parent) {
994                         if (_talloc_steal_internal(new_parent, h) != h) {
995                                 return NULL;
996                         }
997                         return discard_const_p(void, ptr);
998                 }
999         }       
1000
1001         /* it wasn't a parent */
1002         return NULL;
1003 }
1004
1005 /*
1006   remove a secondary reference to a pointer. This undo's what
1007   talloc_reference() has done. The context and pointer arguments
1008   must match those given to a talloc_reference()
1009 */
1010 static inline int talloc_unreference(const void *context, const void *ptr)
1011 {
1012         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1013         struct talloc_reference_handle *h;
1014
1015         if (unlikely(context == NULL)) {
1016                 context = null_context;
1017         }
1018
1019         for (h=tc->refs;h;h=h->next) {
1020                 struct talloc_chunk *p = talloc_parent_chunk(h);
1021                 if (p == NULL) {
1022                         if (context == NULL) break;
1023                 } else if (TC_PTR_FROM_CHUNK(p) == context) {
1024                         break;
1025                 }
1026         }
1027         if (h == NULL) {
1028                 return -1;
1029         }
1030
1031         return _talloc_free_internal(h, __location__);
1032 }
1033
1034 /*
1035   remove a specific parent context from a pointer. This is a more
1036   controlled varient of talloc_free()
1037 */
1038 _PUBLIC_ int talloc_unlink(const void *context, void *ptr)
1039 {
1040         struct talloc_chunk *tc_p, *new_p;
1041         void *new_parent;
1042
1043         if (ptr == NULL) {
1044                 return -1;
1045         }
1046
1047         if (context == NULL) {
1048                 context = null_context;
1049         }
1050
1051         if (talloc_unreference(context, ptr) == 0) {
1052                 return 0;
1053         }
1054
1055         if (context == NULL) {
1056                 if (talloc_parent_chunk(ptr) != NULL) {
1057                         return -1;
1058                 }
1059         } else {
1060                 if (talloc_chunk_from_ptr(context) != talloc_parent_chunk(ptr)) {
1061                         return -1;
1062                 }
1063         }
1064         
1065         tc_p = talloc_chunk_from_ptr(ptr);
1066
1067         if (tc_p->refs == NULL) {
1068                 return _talloc_free_internal(ptr, __location__);
1069         }
1070
1071         new_p = talloc_parent_chunk(tc_p->refs);
1072         if (new_p) {
1073                 new_parent = TC_PTR_FROM_CHUNK(new_p);
1074         } else {
1075                 new_parent = NULL;
1076         }
1077
1078         if (talloc_unreference(new_parent, ptr) != 0) {
1079                 return -1;
1080         }
1081
1082         _talloc_steal_internal(new_parent, ptr);
1083
1084         return 0;
1085 }
1086
1087 /*
1088   add a name to an existing pointer - va_list version
1089 */
1090 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0);
1091
1092 static inline const char *talloc_set_name_v(const void *ptr, const char *fmt, va_list ap)
1093 {
1094         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1095         tc->name = talloc_vasprintf(ptr, fmt, ap);
1096         if (likely(tc->name)) {
1097                 _talloc_set_name_const(tc->name, ".name");
1098         }
1099         return tc->name;
1100 }
1101
1102 /*
1103   add a name to an existing pointer
1104 */
1105 _PUBLIC_ const char *talloc_set_name(const void *ptr, const char *fmt, ...)
1106 {
1107         const char *name;
1108         va_list ap;
1109         va_start(ap, fmt);
1110         name = talloc_set_name_v(ptr, fmt, ap);
1111         va_end(ap);
1112         return name;
1113 }
1114
1115
1116 /*
1117   create a named talloc pointer. Any talloc pointer can be named, and
1118   talloc_named() operates just like talloc() except that it allows you
1119   to name the pointer.
1120 */
1121 _PUBLIC_ void *talloc_named(const void *context, size_t size, const char *fmt, ...)
1122 {
1123         va_list ap;
1124         void *ptr;
1125         const char *name;
1126
1127         ptr = __talloc(context, size);
1128         if (unlikely(ptr == NULL)) return NULL;
1129
1130         va_start(ap, fmt);
1131         name = talloc_set_name_v(ptr, fmt, ap);
1132         va_end(ap);
1133
1134         if (unlikely(name == NULL)) {
1135                 _talloc_free_internal(ptr, __location__);
1136                 return NULL;
1137         }
1138
1139         return ptr;
1140 }
1141
1142 /*
1143   return the name of a talloc ptr, or "UNNAMED"
1144 */
1145 _PUBLIC_ const char *talloc_get_name(const void *ptr)
1146 {
1147         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1148         if (unlikely(tc->name == TALLOC_MAGIC_REFERENCE)) {
1149                 return ".reference";
1150         }
1151         if (likely(tc->name)) {
1152                 return tc->name;
1153         }
1154         return "UNNAMED";
1155 }
1156
1157
1158 /*
1159   check if a pointer has the given name. If it does, return the pointer,
1160   otherwise return NULL
1161 */
1162 _PUBLIC_ void *talloc_check_name(const void *ptr, const char *name)
1163 {
1164         const char *pname;
1165         if (unlikely(ptr == NULL)) return NULL;
1166         pname = talloc_get_name(ptr);
1167         if (likely(pname == name || strcmp(pname, name) == 0)) {
1168                 return discard_const_p(void, ptr);
1169         }
1170         return NULL;
1171 }
1172
1173 static void talloc_abort_type_missmatch(const char *location,
1174                                         const char *name,
1175                                         const char *expected)
1176 {
1177         const char *reason;
1178
1179         reason = talloc_asprintf(NULL,
1180                                  "%s: Type mismatch: name[%s] expected[%s]",
1181                                  location,
1182                                  name?name:"NULL",
1183                                  expected);
1184         if (!reason) {
1185                 reason = "Type mismatch";
1186         }
1187
1188         talloc_abort(reason);
1189 }
1190
1191 _PUBLIC_ void *_talloc_get_type_abort(const void *ptr, const char *name, const char *location)
1192 {
1193         const char *pname;
1194
1195         if (unlikely(ptr == NULL)) {
1196                 talloc_abort_type_missmatch(location, NULL, name);
1197                 return NULL;
1198         }
1199
1200         pname = talloc_get_name(ptr);
1201         if (likely(pname == name || strcmp(pname, name) == 0)) {
1202                 return discard_const_p(void, ptr);
1203         }
1204
1205         talloc_abort_type_missmatch(location, pname, name);
1206         return NULL;
1207 }
1208
1209 /*
1210   this is for compatibility with older versions of talloc
1211 */
1212 _PUBLIC_ void *talloc_init(const char *fmt, ...)
1213 {
1214         va_list ap;
1215         void *ptr;
1216         const char *name;
1217
1218         ptr = __talloc(NULL, 0);
1219         if (unlikely(ptr == NULL)) return NULL;
1220
1221         va_start(ap, fmt);
1222         name = talloc_set_name_v(ptr, fmt, ap);
1223         va_end(ap);
1224
1225         if (unlikely(name == NULL)) {
1226                 _talloc_free_internal(ptr, __location__);
1227                 return NULL;
1228         }
1229
1230         return ptr;
1231 }
1232
1233 /*
1234   this is a replacement for the Samba3 talloc_destroy_pool functionality. It
1235   should probably not be used in new code. It's in here to keep the talloc
1236   code consistent across Samba 3 and 4.
1237 */
1238 _PUBLIC_ void talloc_free_children(void *ptr)
1239 {
1240         struct talloc_chunk *tc;
1241
1242         if (unlikely(ptr == NULL)) {
1243                 return;
1244         }
1245
1246         tc = talloc_chunk_from_ptr(ptr);
1247
1248         while (tc->child) {
1249                 /* we need to work out who will own an abandoned child
1250                    if it cannot be freed. In priority order, the first
1251                    choice is owner of any remaining reference to this
1252                    pointer, the second choice is our parent, and the
1253                    final choice is the null context. */
1254                 void *child = TC_PTR_FROM_CHUNK(tc->child);
1255                 const void *new_parent = null_context;
1256                 if (unlikely(tc->child->refs)) {
1257                         struct talloc_chunk *p = talloc_parent_chunk(tc->child->refs);
1258                         if (p) new_parent = TC_PTR_FROM_CHUNK(p);
1259                 }
1260                 if (unlikely(talloc_free(child) == -1)) {
1261                         if (new_parent == null_context) {
1262                                 struct talloc_chunk *p = talloc_parent_chunk(ptr);
1263                                 if (p) new_parent = TC_PTR_FROM_CHUNK(p);
1264                         }
1265                         _talloc_steal_internal(new_parent, child);
1266                 }
1267         }
1268 }
1269
1270 /* 
1271    Allocate a bit of memory as a child of an existing pointer
1272 */
1273 _PUBLIC_ void *_talloc(const void *context, size_t size)
1274 {
1275         return __talloc(context, size);
1276 }
1277
1278 /*
1279   externally callable talloc_set_name_const()
1280 */
1281 _PUBLIC_ void talloc_set_name_const(const void *ptr, const char *name)
1282 {
1283         _talloc_set_name_const(ptr, name);
1284 }
1285
1286 /*
1287   create a named talloc pointer. Any talloc pointer can be named, and
1288   talloc_named() operates just like talloc() except that it allows you
1289   to name the pointer.
1290 */
1291 _PUBLIC_ void *talloc_named_const(const void *context, size_t size, const char *name)
1292 {
1293         return _talloc_named_const(context, size, name);
1294 }
1295
1296 /* 
1297    free a talloc pointer. This also frees all child pointers of this 
1298    pointer recursively
1299
1300    return 0 if the memory is actually freed, otherwise -1. The memory
1301    will not be freed if the ref_count is > 1 or the destructor (if
1302    any) returns non-zero
1303 */
1304 _PUBLIC_ int _talloc_free(void *ptr, const char *location)
1305 {
1306         struct talloc_chunk *tc;
1307
1308         if (unlikely(ptr == NULL)) {
1309                 return -1;
1310         }
1311         
1312         tc = talloc_chunk_from_ptr(ptr);
1313         
1314         if (unlikely(tc->refs != NULL)) {
1315                 struct talloc_reference_handle *h;
1316
1317                 if (talloc_parent(ptr) == null_context && tc->refs->next == NULL) {
1318                         /* in this case we do know which parent should
1319                            get this pointer, as there is really only
1320                            one parent */
1321                         return talloc_unlink(null_context, ptr);
1322                 }
1323
1324                 talloc_log("ERROR: talloc_free with references at %s\n",
1325                            location);
1326
1327                 for (h=tc->refs; h; h=h->next) {
1328                         talloc_log("\treference at %s\n",
1329                                    h->location);
1330                 }
1331                 return -1;
1332         }
1333         
1334         return _talloc_free_internal(ptr, location);
1335 }
1336
1337
1338
1339 /*
1340   A talloc version of realloc. The context argument is only used if
1341   ptr is NULL
1342 */
1343 _PUBLIC_ void *_talloc_realloc(const void *context, void *ptr, size_t size, const char *name)
1344 {
1345         struct talloc_chunk *tc;
1346         void *new_ptr;
1347         bool malloced = false;
1348         struct talloc_chunk *pool_tc = NULL;
1349
1350         /* size zero is equivalent to free() */
1351         if (unlikely(size == 0)) {
1352                 talloc_unlink(context, ptr);
1353                 return NULL;
1354         }
1355
1356         if (unlikely(size >= MAX_TALLOC_SIZE)) {
1357                 return NULL;
1358         }
1359
1360         /* realloc(NULL) is equivalent to malloc() */
1361         if (ptr == NULL) {
1362                 return _talloc_named_const(context, size, name);
1363         }
1364
1365         tc = talloc_chunk_from_ptr(ptr);
1366
1367         /* don't allow realloc on referenced pointers */
1368         if (unlikely(tc->refs)) {
1369                 return NULL;
1370         }
1371
1372         /* don't let anybody try to realloc a talloc_pool */
1373         if (unlikely(tc->flags & TALLOC_FLAG_POOL)) {
1374                 return NULL;
1375         }
1376
1377         /* don't let anybody try to realloc a talloc_pool */
1378         if (unlikely(tc->flags & TALLOC_FLAG_POOLMEM)) {
1379                 pool_tc = (struct talloc_chunk *)tc->pool;
1380         }
1381
1382 #if (ALWAYS_REALLOC == 0)
1383         /* don't shrink if we have less than 1k to gain */
1384         if (size < tc->size) {
1385                 if (pool_tc) {
1386                         void *next_tc = TC_POOLMEM_NEXT_CHUNK(tc);
1387                         TC_INVALIDATE_SHRINK_CHUNK(tc, size);
1388                         tc->size = size;
1389                         if (next_tc == pool_tc->pool) {
1390                                 pool_tc->pool = TC_POOLMEM_NEXT_CHUNK(tc);
1391                         }
1392                         return ptr;
1393                 } else if ((tc->size - size) < 1024) {
1394                         /*
1395                          * if we call TC_INVALIDATE_SHRINK_CHUNK() here
1396                          * we would need to call TC_UNDEFINE_GROW_CHUNK()
1397                          * after each realloc call, which slows down
1398                          * testing a lot :-(.
1399                          *
1400                          * That is why we only mark memory as undefined here.
1401                          */
1402                         TC_UNDEFINE_SHRINK_CHUNK(tc, size);
1403
1404                         /* do not shrink if we have less than 1k to gain */
1405                         tc->size = size;
1406                         return ptr;
1407                 }
1408         } else if (tc->size == size) {
1409                 /*
1410                  * do not change the pointer if it is exactly
1411                  * the same size.
1412                  */
1413                 return ptr;
1414         }
1415 #endif
1416
1417         /* by resetting magic we catch users of the old memory */
1418         tc->flags |= TALLOC_FLAG_FREE;
1419
1420 #if ALWAYS_REALLOC
1421         if (pool_tc) {
1422                 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE);
1423                 *talloc_pool_objectcount(pool_tc) -= 1;
1424
1425                 if (new_ptr == NULL) {
1426                         new_ptr = malloc(TC_HDR_SIZE+size);
1427                         malloced = true;
1428                 }
1429
1430                 if (new_ptr) {
1431                         memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
1432                         TC_INVALIDATE_FULL_CHUNK(tc);
1433                 }
1434         } else {
1435                 new_ptr = malloc(size + TC_HDR_SIZE);
1436                 if (new_ptr) {
1437                         memcpy(new_ptr, tc, MIN(tc->size, size) + TC_HDR_SIZE);
1438                         free(tc);
1439                 }
1440         }
1441 #else
1442         if (pool_tc) {
1443                 void *next_tc = TC_POOLMEM_NEXT_CHUNK(tc);
1444                 size_t old_chunk_size = TC_POOLMEM_CHUNK_SIZE(tc);
1445                 size_t new_chunk_size = TC_ALIGN16(TC_HDR_SIZE + size);
1446                 size_t space_needed;
1447                 size_t space_left;
1448
1449                 if (*talloc_pool_objectcount(pool_tc) == 2) {
1450                         /*
1451                          * optimize for the case where 'tc' is the only
1452                          * chunk in the pool.
1453                          */
1454                         space_needed = new_chunk_size;
1455                         space_left = pool_tc->size - TALLOC_POOL_HDR_SIZE;
1456
1457                         if (space_left >= space_needed) {
1458                                 size_t old_used = TC_HDR_SIZE + tc->size;
1459                                 size_t new_used = TC_HDR_SIZE + size;
1460                                 pool_tc->pool = TC_POOL_FIRST_CHUNK(pool_tc);
1461 #if defined(DEVELOPER) && defined(VALGRIND_MAKE_MEM_UNDEFINED)
1462                                 /*
1463                                  * we need to prepare the memmove into
1464                                  * the unaccessable area.
1465                                  */
1466                                 {
1467                                         size_t diff = PTR_DIFF(tc, pool_tc->pool);
1468                                         size_t flen = MIN(diff, old_used);
1469                                         char *fptr = (char *)pool_tc->pool;
1470                                         VALGRIND_MAKE_MEM_UNDEFINED(fptr, flen);
1471                                 }
1472 #endif
1473                                 memmove(pool_tc->pool, tc, old_used);
1474                                 new_ptr = pool_tc->pool;
1475
1476                                 TC_UNDEFINE_GROW_CHUNK(tc, size);
1477
1478                                 /*
1479                                  * first we do not align the pool pointer
1480                                  * because we want to invalidate the padding
1481                                  * too.
1482                                  */
1483                                 pool_tc->pool = new_used + (char *)new_ptr;
1484                                 TC_INVALIDATE_POOL(pool_tc);
1485
1486                                 /* now the aligned pointer */
1487                                 pool_tc->pool = new_chunk_size + (char *)new_ptr;
1488                                 goto got_new_ptr;
1489                         }
1490
1491                         next_tc = NULL;
1492                 }
1493
1494                 if (new_chunk_size == old_chunk_size) {
1495                         TC_UNDEFINE_GROW_CHUNK(tc, size);
1496                         tc->flags &= ~TALLOC_FLAG_FREE;
1497                         tc->size = size;
1498                         return ptr;
1499                 }
1500
1501                 if (next_tc == pool_tc->pool) {
1502                         /*
1503                          * optimize for the case where 'tc' is the last
1504                          * chunk in the pool.
1505                          */
1506                         space_needed = new_chunk_size - old_chunk_size;
1507                         space_left = TC_POOL_SPACE_LEFT(pool_tc);
1508
1509                         if (space_left >= space_needed) {
1510                                 TC_UNDEFINE_GROW_CHUNK(tc, size);
1511                                 tc->flags &= ~TALLOC_FLAG_FREE;
1512                                 tc->size = size;
1513                                 pool_tc->pool = TC_POOLMEM_NEXT_CHUNK(tc);
1514                                 return ptr;
1515                         }
1516                 }
1517
1518                 new_ptr = talloc_alloc_pool(tc, size + TC_HDR_SIZE);
1519                 *talloc_pool_objectcount(pool_tc) -= 1;
1520
1521                 if (new_ptr == NULL) {
1522                         new_ptr = malloc(TC_HDR_SIZE+size);
1523                         malloced = true;
1524                 }
1525
1526                 if (new_ptr) {
1527                         memcpy(new_ptr, tc, MIN(tc->size,size) + TC_HDR_SIZE);
1528                         TC_INVALIDATE_FULL_CHUNK(tc);
1529
1530                         if (*talloc_pool_objectcount(pool_tc) == 1) {
1531                                 /*
1532                                  * If the pool is empty now reclaim everything.
1533                                  */
1534                                 pool_tc->pool = TC_POOL_FIRST_CHUNK(pool_tc);
1535                                 TC_INVALIDATE_POOL(pool_tc);
1536                         } else if (next_tc == pool_tc->pool) {
1537                                 /*
1538                                  * If it was reallocated and tc was the last
1539                                  * chunk, we can reclaim the memory of tc.
1540                                  */
1541                                 pool_tc->pool = tc;
1542                         }
1543                 }
1544         }
1545         else {
1546                 new_ptr = realloc(tc, size + TC_HDR_SIZE);
1547         }
1548 got_new_ptr:
1549 #endif
1550         if (unlikely(!new_ptr)) {       
1551                 tc->flags &= ~TALLOC_FLAG_FREE; 
1552                 return NULL; 
1553         }
1554
1555         tc = (struct talloc_chunk *)new_ptr;
1556         tc->flags &= ~TALLOC_FLAG_FREE;
1557         if (malloced) {
1558                 tc->flags &= ~TALLOC_FLAG_POOLMEM;
1559         }
1560         if (tc->parent) {
1561                 tc->parent->child = tc;
1562         }
1563         if (tc->child) {
1564                 tc->child->parent = tc;
1565         }
1566
1567         if (tc->prev) {
1568                 tc->prev->next = tc;
1569         }
1570         if (tc->next) {
1571                 tc->next->prev = tc;
1572         }
1573
1574         tc->size = size;
1575         _talloc_set_name_const(TC_PTR_FROM_CHUNK(tc), name);
1576
1577         return TC_PTR_FROM_CHUNK(tc);
1578 }
1579
1580 /*
1581   a wrapper around talloc_steal() for situations where you are moving a pointer
1582   between two structures, and want the old pointer to be set to NULL
1583 */
1584 _PUBLIC_ void *_talloc_move(const void *new_ctx, const void *_pptr)
1585 {
1586         const void **pptr = discard_const_p(const void *,_pptr);
1587         void *ret = talloc_steal(new_ctx, discard_const_p(void, *pptr));
1588         (*pptr) = NULL;
1589         return ret;
1590 }
1591
1592 /*
1593   return the total size of a talloc pool (subtree)
1594 */
1595 _PUBLIC_ size_t talloc_total_size(const void *ptr)
1596 {
1597         size_t total = 0;
1598         struct talloc_chunk *c, *tc;
1599
1600         if (ptr == NULL) {
1601                 ptr = null_context;
1602         }
1603         if (ptr == NULL) {
1604                 return 0;
1605         }
1606
1607         tc = talloc_chunk_from_ptr(ptr);
1608
1609         if (tc->flags & TALLOC_FLAG_LOOP) {
1610                 return 0;
1611         }
1612
1613         tc->flags |= TALLOC_FLAG_LOOP;
1614
1615         if (likely(tc->name != TALLOC_MAGIC_REFERENCE)) {
1616                 total = tc->size;
1617         }
1618         for (c=tc->child;c;c=c->next) {
1619                 total += talloc_total_size(TC_PTR_FROM_CHUNK(c));
1620         }
1621
1622         tc->flags &= ~TALLOC_FLAG_LOOP;
1623
1624         return total;
1625 }
1626
1627 /*
1628   return the total number of blocks in a talloc pool (subtree)
1629 */
1630 _PUBLIC_ size_t talloc_total_blocks(const void *ptr)
1631 {
1632         size_t total = 0;
1633         struct talloc_chunk *c, *tc;
1634
1635         if (ptr == NULL) {
1636                 ptr = null_context;
1637         }
1638         if (ptr == NULL) {
1639                 return 0;
1640         }
1641
1642         tc = talloc_chunk_from_ptr(ptr);
1643
1644         if (tc->flags & TALLOC_FLAG_LOOP) {
1645                 return 0;
1646         }
1647
1648         tc->flags |= TALLOC_FLAG_LOOP;
1649
1650         total++;
1651         for (c=tc->child;c;c=c->next) {
1652                 total += talloc_total_blocks(TC_PTR_FROM_CHUNK(c));
1653         }
1654
1655         tc->flags &= ~TALLOC_FLAG_LOOP;
1656
1657         return total;
1658 }
1659
1660 /*
1661   return the number of external references to a pointer
1662 */
1663 _PUBLIC_ size_t talloc_reference_count(const void *ptr)
1664 {
1665         struct talloc_chunk *tc = talloc_chunk_from_ptr(ptr);
1666         struct talloc_reference_handle *h;
1667         size_t ret = 0;
1668
1669         for (h=tc->refs;h;h=h->next) {
1670                 ret++;
1671         }
1672         return ret;
1673 }
1674
1675 /*
1676   report on memory usage by all children of a pointer, giving a full tree view
1677 */
1678 _PUBLIC_ void talloc_report_depth_cb(const void *ptr, int depth, int max_depth,
1679                             void (*callback)(const void *ptr,
1680                                              int depth, int max_depth,
1681                                              int is_ref,
1682                                              void *private_data),
1683                             void *private_data)
1684 {
1685         struct talloc_chunk *c, *tc;
1686
1687         if (ptr == NULL) {
1688                 ptr = null_context;
1689         }
1690         if (ptr == NULL) return;
1691
1692         tc = talloc_chunk_from_ptr(ptr);
1693
1694         if (tc->flags & TALLOC_FLAG_LOOP) {
1695                 return;
1696         }
1697
1698         callback(ptr, depth, max_depth, 0, private_data);
1699
1700         if (max_depth >= 0 && depth >= max_depth) {
1701                 return;
1702         }
1703
1704         tc->flags |= TALLOC_FLAG_LOOP;
1705         for (c=tc->child;c;c=c->next) {
1706                 if (c->name == TALLOC_MAGIC_REFERENCE) {
1707                         struct talloc_reference_handle *h = (struct talloc_reference_handle *)TC_PTR_FROM_CHUNK(c);
1708                         callback(h->ptr, depth + 1, max_depth, 1, private_data);
1709                 } else {
1710                         talloc_report_depth_cb(TC_PTR_FROM_CHUNK(c), depth + 1, max_depth, callback, private_data);
1711                 }
1712         }
1713         tc->flags &= ~TALLOC_FLAG_LOOP;
1714 }
1715
1716 static void talloc_report_depth_FILE_helper(const void *ptr, int depth, int max_depth, int is_ref, void *_f)
1717 {
1718         const char *name = talloc_get_name(ptr);
1719         FILE *f = (FILE *)_f;
1720
1721         if (is_ref) {
1722                 fprintf(f, "%*sreference to: %s\n", depth*4, "", name);
1723                 return;
1724         }
1725
1726         if (depth == 0) {
1727                 fprintf(f,"%stalloc report on '%s' (total %6lu bytes in %3lu blocks)\n", 
1728                         (max_depth < 0 ? "full " :""), name,
1729                         (unsigned long)talloc_total_size(ptr),
1730                         (unsigned long)talloc_total_blocks(ptr));
1731                 return;
1732         }
1733
1734         fprintf(f, "%*s%-30s contains %6lu bytes in %3lu blocks (ref %d) %p\n", 
1735                 depth*4, "",
1736                 name,
1737                 (unsigned long)talloc_total_size(ptr),
1738                 (unsigned long)talloc_total_blocks(ptr),
1739                 (int)talloc_reference_count(ptr), ptr);
1740
1741 #if 0
1742         fprintf(f, "content: ");
1743         if (talloc_total_size(ptr)) {
1744                 int tot = talloc_total_size(ptr);
1745                 int i;
1746
1747                 for (i = 0; i < tot; i++) {
1748                         if ((((char *)ptr)[i] > 31) && (((char *)ptr)[i] < 126)) {
1749                                 fprintf(f, "%c", ((char *)ptr)[i]);
1750                         } else {
1751                                 fprintf(f, "~%02x", ((char *)ptr)[i]);
1752                         }
1753                 }
1754         }
1755         fprintf(f, "\n");
1756 #endif
1757 }
1758
1759 /*
1760   report on memory usage by all children of a pointer, giving a full tree view
1761 */
1762 _PUBLIC_ void talloc_report_depth_file(const void *ptr, int depth, int max_depth, FILE *f)
1763 {
1764         if (f) {
1765                 talloc_report_depth_cb(ptr, depth, max_depth, talloc_report_depth_FILE_helper, f);
1766                 fflush(f);
1767         }
1768 }
1769
1770 /*
1771   report on memory usage by all children of a pointer, giving a full tree view
1772 */
1773 _PUBLIC_ void talloc_report_full(const void *ptr, FILE *f)
1774 {
1775         talloc_report_depth_file(ptr, 0, -1, f);
1776 }
1777
1778 /*
1779   report on memory usage by all children of a pointer
1780 */
1781 _PUBLIC_ void talloc_report(const void *ptr, FILE *f)
1782 {
1783         talloc_report_depth_file(ptr, 0, 1, f);
1784 }
1785
1786 /*
1787   report on any memory hanging off the null context
1788 */
1789 static void talloc_report_null(void)
1790 {
1791         if (talloc_total_size(null_context) != 0) {
1792                 talloc_report(null_context, stderr);
1793         }
1794 }
1795
1796 /*
1797   report on any memory hanging off the null context
1798 */
1799 static void talloc_report_null_full(void)
1800 {
1801         if (talloc_total_size(null_context) != 0) {
1802                 talloc_report_full(null_context, stderr);
1803         }
1804 }
1805
1806 /*
1807   enable tracking of the NULL context
1808 */
1809 _PUBLIC_ void talloc_enable_null_tracking(void)
1810 {
1811         if (null_context == NULL) {
1812                 null_context = _talloc_named_const(NULL, 0, "null_context");
1813                 if (autofree_context != NULL) {
1814                         talloc_reparent(NULL, null_context, autofree_context);
1815                 }
1816         }
1817 }
1818
1819 /*
1820   enable tracking of the NULL context, not moving the autofree context
1821   into the NULL context. This is needed for the talloc testsuite
1822 */
1823 _PUBLIC_ void talloc_enable_null_tracking_no_autofree(void)
1824 {
1825         if (null_context == NULL) {
1826                 null_context = _talloc_named_const(NULL, 0, "null_context");
1827         }
1828 }
1829
1830 /*
1831   disable tracking of the NULL context
1832 */
1833 _PUBLIC_ void talloc_disable_null_tracking(void)
1834 {
1835         if (null_context != NULL) {
1836                 /* we have to move any children onto the real NULL
1837                    context */
1838                 struct talloc_chunk *tc, *tc2;
1839                 tc = talloc_chunk_from_ptr(null_context);
1840                 for (tc2 = tc->child; tc2; tc2=tc2->next) {
1841                         if (tc2->parent == tc) tc2->parent = NULL;
1842                         if (tc2->prev == tc) tc2->prev = NULL;
1843                 }
1844                 for (tc2 = tc->next; tc2; tc2=tc2->next) {
1845                         if (tc2->parent == tc) tc2->parent = NULL;
1846                         if (tc2->prev == tc) tc2->prev = NULL;
1847                 }
1848                 tc->child = NULL;
1849                 tc->next = NULL;
1850         }
1851         talloc_free(null_context);
1852         null_context = NULL;
1853 }
1854
1855 /*
1856   enable leak reporting on exit
1857 */
1858 _PUBLIC_ void talloc_enable_leak_report(void)
1859 {
1860         talloc_enable_null_tracking();
1861         atexit(talloc_report_null);
1862 }
1863
1864 /*
1865   enable full leak reporting on exit
1866 */
1867 _PUBLIC_ void talloc_enable_leak_report_full(void)
1868 {
1869         talloc_enable_null_tracking();
1870         atexit(talloc_report_null_full);
1871 }
1872
1873 /* 
1874    talloc and zero memory. 
1875 */
1876 _PUBLIC_ void *_talloc_zero(const void *ctx, size_t size, const char *name)
1877 {
1878         void *p = _talloc_named_const(ctx, size, name);
1879
1880         if (p) {
1881                 memset(p, '\0', size);
1882         }
1883
1884         return p;
1885 }
1886
1887 /*
1888   memdup with a talloc. 
1889 */
1890 _PUBLIC_ void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name)
1891 {
1892         void *newp = _talloc_named_const(t, size, name);
1893
1894         if (likely(newp)) {
1895                 memcpy(newp, p, size);
1896         }
1897
1898         return newp;
1899 }
1900
1901 static inline char *__talloc_strlendup(const void *t, const char *p, size_t len)
1902 {
1903         char *ret;
1904
1905         ret = (char *)__talloc(t, len + 1);
1906         if (unlikely(!ret)) return NULL;
1907
1908         memcpy(ret, p, len);
1909         ret[len] = 0;
1910
1911         _talloc_set_name_const(ret, ret);
1912         return ret;
1913 }
1914
1915 /*
1916   strdup with a talloc
1917 */
1918 _PUBLIC_ char *talloc_strdup(const void *t, const char *p)
1919 {
1920         if (unlikely(!p)) return NULL;
1921         return __talloc_strlendup(t, p, strlen(p));
1922 }
1923
1924 /*
1925   strndup with a talloc
1926 */
1927 _PUBLIC_ char *talloc_strndup(const void *t, const char *p, size_t n)
1928 {
1929         if (unlikely(!p)) return NULL;
1930         return __talloc_strlendup(t, p, strnlen(p, n));
1931 }
1932
1933 static inline char *__talloc_strlendup_append(char *s, size_t slen,
1934                                               const char *a, size_t alen)
1935 {
1936         char *ret;
1937
1938         ret = talloc_realloc(NULL, s, char, slen + alen + 1);
1939         if (unlikely(!ret)) return NULL;
1940
1941         /* append the string and the trailing \0 */
1942         memcpy(&ret[slen], a, alen);
1943         ret[slen+alen] = 0;
1944
1945         _talloc_set_name_const(ret, ret);
1946         return ret;
1947 }
1948
1949 /*
1950  * Appends at the end of the string.
1951  */
1952 _PUBLIC_ char *talloc_strdup_append(char *s, const char *a)
1953 {
1954         if (unlikely(!s)) {
1955                 return talloc_strdup(NULL, a);
1956         }
1957
1958         if (unlikely(!a)) {
1959                 return s;
1960         }
1961
1962         return __talloc_strlendup_append(s, strlen(s), a, strlen(a));
1963 }
1964
1965 /*
1966  * Appends at the end of the talloc'ed buffer,
1967  * not the end of the string.
1968  */
1969 _PUBLIC_ char *talloc_strdup_append_buffer(char *s, const char *a)
1970 {
1971         size_t slen;
1972
1973         if (unlikely(!s)) {
1974                 return talloc_strdup(NULL, a);
1975         }
1976
1977         if (unlikely(!a)) {
1978                 return s;
1979         }
1980
1981         slen = talloc_get_size(s);
1982         if (likely(slen > 0)) {
1983                 slen--;
1984         }
1985
1986         return __talloc_strlendup_append(s, slen, a, strlen(a));
1987 }
1988
1989 /*
1990  * Appends at the end of the string.
1991  */
1992 _PUBLIC_ char *talloc_strndup_append(char *s, const char *a, size_t n)
1993 {
1994         if (unlikely(!s)) {
1995                 return talloc_strdup(NULL, a);
1996         }
1997
1998         if (unlikely(!a)) {
1999                 return s;
2000         }
2001
2002         return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n));
2003 }
2004
2005 /*
2006  * Appends at the end of the talloc'ed buffer,
2007  * not the end of the string.
2008  */
2009 _PUBLIC_ char *talloc_strndup_append_buffer(char *s, const char *a, size_t n)
2010 {
2011         size_t slen;
2012
2013         if (unlikely(!s)) {
2014                 return talloc_strdup(NULL, a);
2015         }
2016
2017         if (unlikely(!a)) {
2018                 return s;
2019         }
2020
2021         slen = talloc_get_size(s);
2022         if (likely(slen > 0)) {
2023                 slen--;
2024         }
2025
2026         return __talloc_strlendup_append(s, slen, a, strnlen(a, n));
2027 }
2028
2029 #ifndef HAVE_VA_COPY
2030 #ifdef HAVE___VA_COPY
2031 #define va_copy(dest, src) __va_copy(dest, src)
2032 #else
2033 #define va_copy(dest, src) (dest) = (src)
2034 #endif
2035 #endif
2036
2037 _PUBLIC_ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap)
2038 {
2039         int len;
2040         char *ret;
2041         va_list ap2;
2042         char c;
2043
2044         /* this call looks strange, but it makes it work on older solaris boxes */
2045         va_copy(ap2, ap);
2046         len = vsnprintf(&c, 1, fmt, ap2);
2047         va_end(ap2);
2048         if (unlikely(len < 0)) {
2049                 return NULL;
2050         }
2051
2052         ret = (char *)__talloc(t, len+1);
2053         if (unlikely(!ret)) return NULL;
2054
2055         va_copy(ap2, ap);
2056         vsnprintf(ret, len+1, fmt, ap2);
2057         va_end(ap2);
2058
2059         _talloc_set_name_const(ret, ret);
2060         return ret;
2061 }
2062
2063
2064 /*
2065   Perform string formatting, and return a pointer to newly allocated
2066   memory holding the result, inside a memory pool.
2067  */
2068 _PUBLIC_ char *talloc_asprintf(const void *t, const char *fmt, ...)
2069 {
2070         va_list ap;
2071         char *ret;
2072
2073         va_start(ap, fmt);
2074         ret = talloc_vasprintf(t, fmt, ap);
2075         va_end(ap);
2076         return ret;
2077 }
2078
2079 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
2080                                                  const char *fmt, va_list ap)
2081                                                  PRINTF_ATTRIBUTE(3,0);
2082
2083 static inline char *__talloc_vaslenprintf_append(char *s, size_t slen,
2084                                                  const char *fmt, va_list ap)
2085 {
2086         ssize_t alen;
2087         va_list ap2;
2088         char c;
2089
2090         va_copy(ap2, ap);
2091         alen = vsnprintf(&c, 1, fmt, ap2);
2092         va_end(ap2);
2093
2094         if (alen <= 0) {
2095                 /* Either the vsnprintf failed or the format resulted in
2096                  * no characters being formatted. In the former case, we
2097                  * ought to return NULL, in the latter we ought to return
2098                  * the original string. Most current callers of this
2099                  * function expect it to never return NULL.
2100                  */
2101                 return s;
2102         }
2103
2104         s = talloc_realloc(NULL, s, char, slen + alen + 1);
2105         if (!s) return NULL;
2106
2107         va_copy(ap2, ap);
2108         vsnprintf(s + slen, alen + 1, fmt, ap2);
2109         va_end(ap2);
2110
2111         _talloc_set_name_const(s, s);
2112         return s;
2113 }
2114
2115 /**
2116  * Realloc @p s to append the formatted result of @p fmt and @p ap,
2117  * and return @p s, which may have moved.  Good for gradually
2118  * accumulating output into a string buffer. Appends at the end
2119  * of the string.
2120  **/
2121 _PUBLIC_ char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap)
2122 {
2123         if (unlikely(!s)) {
2124                 return talloc_vasprintf(NULL, fmt, ap);
2125         }
2126
2127         return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap);
2128 }
2129
2130 /**
2131  * Realloc @p s to append the formatted result of @p fmt and @p ap,
2132  * and return @p s, which may have moved. Always appends at the
2133  * end of the talloc'ed buffer, not the end of the string.
2134  **/
2135 _PUBLIC_ char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap)
2136 {
2137         size_t slen;
2138
2139         if (unlikely(!s)) {
2140                 return talloc_vasprintf(NULL, fmt, ap);
2141         }
2142
2143         slen = talloc_get_size(s);
2144         if (likely(slen > 0)) {
2145                 slen--;
2146         }
2147
2148         return __talloc_vaslenprintf_append(s, slen, fmt, ap);
2149 }
2150
2151 /*
2152   Realloc @p s to append the formatted result of @p fmt and return @p
2153   s, which may have moved.  Good for gradually accumulating output
2154   into a string buffer.
2155  */
2156 _PUBLIC_ char *talloc_asprintf_append(char *s, const char *fmt, ...)
2157 {
2158         va_list ap;
2159
2160         va_start(ap, fmt);
2161         s = talloc_vasprintf_append(s, fmt, ap);
2162         va_end(ap);
2163         return s;
2164 }
2165
2166 /*
2167   Realloc @p s to append the formatted result of @p fmt and return @p
2168   s, which may have moved.  Good for gradually accumulating output
2169   into a buffer.
2170  */
2171 _PUBLIC_ char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...)
2172 {
2173         va_list ap;
2174
2175         va_start(ap, fmt);
2176         s = talloc_vasprintf_append_buffer(s, fmt, ap);
2177         va_end(ap);
2178         return s;
2179 }
2180
2181 /*
2182   alloc an array, checking for integer overflow in the array size
2183 */
2184 _PUBLIC_ void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name)
2185 {
2186         if (count >= MAX_TALLOC_SIZE/el_size) {
2187                 return NULL;
2188         }
2189         return _talloc_named_const(ctx, el_size * count, name);
2190 }
2191
2192 /*
2193   alloc an zero array, checking for integer overflow in the array size
2194 */
2195 _PUBLIC_ void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name)
2196 {
2197         if (count >= MAX_TALLOC_SIZE/el_size) {
2198                 return NULL;
2199         }
2200         return _talloc_zero(ctx, el_size * count, name);
2201 }
2202
2203 /*
2204   realloc an array, checking for integer overflow in the array size
2205 */
2206 _PUBLIC_ void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name)
2207 {
2208         if (count >= MAX_TALLOC_SIZE/el_size) {
2209                 return NULL;
2210         }
2211         return _talloc_realloc(ctx, ptr, el_size * count, name);
2212 }
2213
2214 /*
2215   a function version of talloc_realloc(), so it can be passed as a function pointer
2216   to libraries that want a realloc function (a realloc function encapsulates
2217   all the basic capabilities of an allocation library, which is why this is useful)
2218 */
2219 _PUBLIC_ void *talloc_realloc_fn(const void *context, void *ptr, size_t size)
2220 {
2221         return _talloc_realloc(context, ptr, size, NULL);
2222 }
2223
2224
2225 static int talloc_autofree_destructor(void *ptr)
2226 {
2227         autofree_context = NULL;
2228         return 0;
2229 }
2230
2231 static void talloc_autofree(void)
2232 {
2233         talloc_free(autofree_context);
2234 }
2235
2236 /*
2237   return a context which will be auto-freed on exit
2238   this is useful for reducing the noise in leak reports
2239 */
2240 _PUBLIC_ void *talloc_autofree_context(void)
2241 {
2242         if (autofree_context == NULL) {
2243                 autofree_context = _talloc_named_const(NULL, 0, "autofree_context");
2244                 talloc_set_destructor(autofree_context, talloc_autofree_destructor);
2245                 atexit(talloc_autofree);
2246         }
2247         return autofree_context;
2248 }
2249
2250 _PUBLIC_ size_t talloc_get_size(const void *context)
2251 {
2252         struct talloc_chunk *tc;
2253
2254         if (context == NULL) {
2255                 context = null_context;
2256         }
2257         if (context == NULL) {
2258                 return 0;
2259         }
2260
2261         tc = talloc_chunk_from_ptr(context);
2262
2263         return tc->size;
2264 }
2265
2266 /*
2267   find a parent of this context that has the given name, if any
2268 */
2269 _PUBLIC_ void *talloc_find_parent_byname(const void *context, const char *name)
2270 {
2271         struct talloc_chunk *tc;
2272
2273         if (context == NULL) {
2274                 return NULL;
2275         }
2276
2277         tc = talloc_chunk_from_ptr(context);
2278         while (tc) {
2279                 if (tc->name && strcmp(tc->name, name) == 0) {
2280                         return TC_PTR_FROM_CHUNK(tc);
2281                 }
2282                 while (tc && tc->prev) tc = tc->prev;
2283                 if (tc) {
2284                         tc = tc->parent;
2285                 }
2286         }
2287         return NULL;
2288 }
2289
2290 /*
2291   show the parentage of a context
2292 */
2293 _PUBLIC_ void talloc_show_parents(const void *context, FILE *file)
2294 {
2295         struct talloc_chunk *tc;
2296
2297         if (context == NULL) {
2298                 fprintf(file, "talloc no parents for NULL\n");
2299                 return;
2300         }
2301
2302         tc = talloc_chunk_from_ptr(context);
2303         fprintf(file, "talloc parents of '%s'\n", talloc_get_name(context));
2304         while (tc) {
2305                 fprintf(file, "\t'%s'\n", talloc_get_name(TC_PTR_FROM_CHUNK(tc)));
2306                 while (tc && tc->prev) tc = tc->prev;
2307                 if (tc) {
2308                         tc = tc->parent;
2309                 }
2310         }
2311         fflush(file);
2312 }
2313
2314 /*
2315   return 1 if ptr is a parent of context
2316 */
2317 static int _talloc_is_parent(const void *context, const void *ptr, int depth)
2318 {
2319         struct talloc_chunk *tc;
2320
2321         if (context == NULL) {
2322                 return 0;
2323         }
2324
2325         tc = talloc_chunk_from_ptr(context);
2326         while (tc && depth > 0) {
2327                 if (TC_PTR_FROM_CHUNK(tc) == ptr) return 1;
2328                 while (tc && tc->prev) tc = tc->prev;
2329                 if (tc) {
2330                         tc = tc->parent;
2331                         depth--;
2332                 }
2333         }
2334         return 0;
2335 }
2336
2337 /*
2338   return 1 if ptr is a parent of context
2339 */
2340 _PUBLIC_ int talloc_is_parent(const void *context, const void *ptr)
2341 {
2342         return _talloc_is_parent(context, ptr, TALLOC_MAX_DEPTH);
2343 }