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