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