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