Added talloc_strdup() funcion.
[samba.git] / source3 / lib / talloc.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 3.0
4    Samba temporary memory allocation functions
5    Copyright (C) Andrew Tridgell 2000
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 /* this is a very simple temporary memory allocator. To use it do the following:
23
24    1) when you first want to allocate a pool of meomry use
25    talloc_init() and save the resulting context pointer somewhere
26
27    2) to allocate memory use talloc()
28
29    3) when _all_ of the memory allocated using this context is no longer needed
30    use talloc_destroy()
31
32    talloc does not zero the memory. It guarantees memory of a
33    TALLOC_ALIGN alignment
34 */
35
36 #include "includes.h"
37
38 /* initialissa talloc context. */
39 TALLOC_CTX *talloc_init(void)
40 {
41         TALLOC_CTX *t;
42
43         t = (TALLOC_CTX *)malloc(sizeof(*t));
44         if (!t) return NULL;
45
46         t->list = NULL;
47         t->total_alloc_size = 0;
48
49         return t;
50 }
51
52 /* allocate a bit of memory from the specified pool */
53 void *talloc(TALLOC_CTX *t, size_t size)
54 {
55         void *p;
56         struct talloc_chunk *tc;
57
58         if (size == 0) {
59                 /* debugging value used to track down
60                    memory problems. BAD_PTR is defined
61                    in talloc.h */
62                 p = BAD_PTR;
63                 return p;
64         }
65
66         p = malloc(size);
67         if (!p) return p;
68
69         tc = malloc(sizeof(*tc));
70         if (!tc) {
71                 free(p);
72                 return NULL;
73         }
74
75         tc->ptr = p;
76         tc->size = size;
77         tc->next = t->list;
78         t->list = tc;
79         t->total_alloc_size += size;
80
81         return p;
82 }
83
84 /* a talloc version of realloc */
85 void *talloc_realloc(TALLOC_CTX *t, void *ptr, size_t size)
86 {
87         struct talloc_chunk *tc;
88
89         for (tc=t->list; tc; tc=tc->next) {
90                 if (tc->ptr == ptr) {
91                         ptr = realloc(ptr, size);
92                         if (ptr) {
93                                 t->total_alloc_size += (size - tc->size);
94                                 tc->size = size;
95                                 tc->ptr = ptr;
96                         }
97                         return ptr;
98                 }
99         }
100         return NULL;
101 }
102
103 /* destroy a whole pool */
104 void talloc_destroy_pool(TALLOC_CTX *t)
105 {
106         struct talloc_chunk *c;
107         
108         if (!t)
109                 return;
110
111         while (t->list) {
112                 c = t->list->next;
113                 if (t->list->ptr) free(t->list->ptr);
114                 free(t->list);
115                 t->list = c;
116         }
117
118         t->list = NULL;
119         t->total_alloc_size = 0;
120 }
121
122 /* destroy a whole pool including the context */
123 void talloc_destroy(TALLOC_CTX *t)
124 {
125         if (!t)
126                 return;
127         talloc_destroy_pool(t);
128         memset(t, 0, sizeof(*t));
129         free(t);
130 }
131
132 /* return the current total size of the pool. */
133 size_t talloc_pool_size(TALLOC_CTX *t)
134 {
135         return t->total_alloc_size;
136 }
137
138 /* talloc and zero memory. */
139 void *talloc_zero(TALLOC_CTX *t, size_t size)
140 {
141         void *p = talloc(t, size);
142
143         if (p)
144                 memset(p, '\0', size);
145
146         return p;
147 }
148
149 /* memdup with a talloc. */
150 void *talloc_memdup(TALLOC_CTX *t, void *p, size_t size)
151 {
152         void *newp = talloc(t,size);
153
154         if (!newp)
155                 return 0;
156
157         memcpy(newp, p, size);
158
159         return newp;
160 }
161
162 /* strdup with a talloc */
163 char *talloc_strdup(TALLOC_CTX *t, char *p)
164 {
165         return talloc_memdup(t, p, strlen(p) + 1);
166 }