source: win32/libtalloc-2.0.1/src/talloc.c @ 262

Last change on this file since 262 was 195, checked in by tim, 15 years ago

removed talloc from mainline build tree, opting instead to depend upon libtalloc-dev

win32 builds depend up on modified libtalloc stored outside of trunk

miscellaneous other build fixes

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