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