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