/src/avahi/avahi-common/malloc.c
Line | Count | Source (jump to first uncovered line) |
1 | | /*** |
2 | | This file is part of avahi. |
3 | | |
4 | | avahi is free software; you can redistribute it and/or modify it |
5 | | under the terms of the GNU Lesser General Public License as |
6 | | published by the Free Software Foundation; either version 2.1 of the |
7 | | License, or (at your option) any later version. |
8 | | |
9 | | avahi is distributed in the hope that it will be useful, but WITHOUT |
10 | | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
11 | | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General |
12 | | Public License for more details. |
13 | | |
14 | | You should have received a copy of the GNU Lesser General Public |
15 | | License along with avahi; if not, write to the Free Software |
16 | | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
17 | | USA. |
18 | | ***/ |
19 | | |
20 | | #ifdef HAVE_CONFIG_H |
21 | | #include <config.h> |
22 | | #endif |
23 | | |
24 | | #include <stdlib.h> |
25 | | #include <string.h> |
26 | | #include <assert.h> |
27 | | #include <stdio.h> |
28 | | #include <unistd.h> |
29 | | |
30 | | #include "malloc.h" |
31 | | |
32 | | #ifndef va_copy |
33 | | #ifdef __va_copy |
34 | | #define va_copy(DEST,SRC) __va_copy((DEST),(SRC)) |
35 | | #else |
36 | | #define va_copy(DEST,SRC) memcpy(&(DEST), &(SRC), sizeof(va_list)) |
37 | | #endif |
38 | | #endif |
39 | | |
40 | | static const AvahiAllocator *allocator = NULL; |
41 | | |
42 | | static void oom(void) AVAHI_GCC_NORETURN; |
43 | | |
44 | 0 | static void oom(void) { |
45 | |
|
46 | 0 | static const char msg[] = "Out of memory, aborting ...\n"; |
47 | 0 | const char *n = msg; |
48 | |
|
49 | 0 | while (strlen(n) > 0) { |
50 | 0 | ssize_t r; |
51 | |
|
52 | 0 | if ((r = write(2, n, strlen(n))) < 0) |
53 | 0 | break; |
54 | | |
55 | 0 | n += r; |
56 | 0 | } |
57 | |
|
58 | 0 | abort(); |
59 | 0 | } |
60 | | |
61 | | /* Default implementation for avahi_malloc() */ |
62 | 257k | static void* xmalloc(size_t size) { |
63 | 257k | void *p; |
64 | | |
65 | 257k | if (size == 0) |
66 | 0 | return NULL; |
67 | | |
68 | 257k | if (!(p = malloc(size))) |
69 | 0 | oom(); |
70 | | |
71 | 257k | return p; |
72 | 257k | } |
73 | | |
74 | | /* Default implementation for avahi_realloc() */ |
75 | 1.22k | static void *xrealloc(void *p, size_t size) { |
76 | | |
77 | 1.22k | if (size == 0) { |
78 | 0 | free(p); |
79 | 0 | return NULL; |
80 | 0 | } |
81 | | |
82 | 1.22k | if (!(p = realloc(p, size))) |
83 | 0 | oom(); |
84 | | |
85 | 1.22k | return p; |
86 | 1.22k | } |
87 | | |
88 | | /* Default implementation for avahi_calloc() */ |
89 | 1.06k | static void *xcalloc(size_t nmemb, size_t size) { |
90 | 1.06k | void *p; |
91 | | |
92 | 1.06k | if (size == 0 || nmemb == 0) |
93 | 0 | return NULL; |
94 | | |
95 | 1.06k | if (!(p = calloc(nmemb, size))) |
96 | 0 | oom(); |
97 | | |
98 | 1.06k | return p; |
99 | 1.06k | } |
100 | | |
101 | 257k | void *avahi_malloc(size_t size) { |
102 | | |
103 | 257k | if (size <= 0) |
104 | 0 | return NULL; |
105 | | |
106 | 257k | if (!allocator) |
107 | 257k | return xmalloc(size); |
108 | | |
109 | 0 | assert(allocator->malloc); |
110 | 0 | return allocator->malloc(size); |
111 | 0 | } |
112 | | |
113 | 1.06k | void *avahi_malloc0(size_t size) { |
114 | 1.06k | void *p; |
115 | | |
116 | 1.06k | if (size <= 0) |
117 | 0 | return NULL; |
118 | | |
119 | 1.06k | if (!allocator) |
120 | 1.06k | return xcalloc(1, size); |
121 | | |
122 | 0 | if (allocator->calloc) |
123 | 0 | return allocator->calloc(1, size); |
124 | | |
125 | 0 | assert(allocator->malloc); |
126 | 0 | if ((p = allocator->malloc(size))) |
127 | 0 | memset(p, 0, size); |
128 | |
|
129 | 0 | return p; |
130 | 0 | } |
131 | | |
132 | 261k | void avahi_free(void *p) { |
133 | | |
134 | 261k | if (!p) |
135 | 3.12k | return; |
136 | | |
137 | 258k | if (!allocator) { |
138 | 258k | free(p); |
139 | 258k | return; |
140 | 258k | } |
141 | | |
142 | 0 | assert(allocator->free); |
143 | 0 | allocator->free(p); |
144 | 0 | } |
145 | | |
146 | 1.22k | void *avahi_realloc(void *p, size_t size) { |
147 | | |
148 | 1.22k | if (size == 0) { |
149 | 0 | avahi_free(p); |
150 | 0 | return NULL; |
151 | 0 | } |
152 | | |
153 | 1.22k | if (!allocator) |
154 | 1.22k | return xrealloc(p, size); |
155 | | |
156 | 0 | assert(allocator->realloc); |
157 | 0 | return allocator->realloc(p, size); |
158 | 0 | } |
159 | | |
160 | 24.5k | char *avahi_strdup(const char *s) { |
161 | 24.5k | char *r; |
162 | 24.5k | size_t size; |
163 | | |
164 | 24.5k | if (!s) |
165 | 0 | return NULL; |
166 | | |
167 | 24.5k | size = strlen(s); |
168 | 24.5k | if (!(r = avahi_malloc(size+1))) |
169 | 0 | return NULL; |
170 | | |
171 | 24.5k | memcpy(r, s, size+1); |
172 | 24.5k | return r; |
173 | 24.5k | } |
174 | | |
175 | 0 | char *avahi_strndup(const char *s, size_t max) { |
176 | 0 | char *r; |
177 | 0 | size_t size; |
178 | 0 | const char *p; |
179 | |
|
180 | 0 | if (!s) |
181 | 0 | return NULL; |
182 | | |
183 | 0 | for (p = s, size = 0; |
184 | 0 | size < max && *p; |
185 | 0 | p++, size++); |
186 | |
|
187 | 0 | if (!(r = avahi_new(char, size+1))) |
188 | 0 | return NULL; |
189 | | |
190 | 0 | memcpy(r, s, size); |
191 | 0 | r[size] = 0; |
192 | 0 | return r; |
193 | 0 | } |
194 | | |
195 | | /* Change the allocator */ |
196 | 0 | void avahi_set_allocator(const AvahiAllocator *a) { |
197 | 0 | allocator = a; |
198 | 0 | } |
199 | | |
200 | 4.02k | char *avahi_strdup_vprintf(const char *fmt, va_list ap) { |
201 | 4.02k | size_t len = 80; |
202 | 4.02k | char *buf; |
203 | | |
204 | 4.02k | assert(fmt); |
205 | | |
206 | 4.02k | if (!(buf = avahi_malloc(len))) |
207 | 0 | return NULL; |
208 | | |
209 | 5.25k | for (;;) { |
210 | 5.25k | int n; |
211 | 5.25k | char *nbuf; |
212 | 5.25k | va_list ap2; |
213 | | |
214 | 5.25k | va_copy (ap2, ap); |
215 | 5.25k | n = vsnprintf(buf, len, fmt, ap2); |
216 | 5.25k | va_end (ap2); |
217 | | |
218 | 5.25k | if (n >= 0 && n < (int) len) |
219 | 4.02k | return buf; |
220 | | |
221 | 1.22k | if (n >= 0) |
222 | 1.22k | len = n+1; |
223 | 0 | else |
224 | 0 | len *= 2; |
225 | | |
226 | 1.22k | if (!(nbuf = avahi_realloc(buf, len))) { |
227 | 0 | avahi_free(buf); |
228 | 0 | return NULL; |
229 | 0 | } |
230 | | |
231 | 1.22k | buf = nbuf; |
232 | 1.22k | } |
233 | 4.02k | } |
234 | | |
235 | 4.02k | char *avahi_strdup_printf(const char *fmt, ... ) { |
236 | 4.02k | char *s; |
237 | 4.02k | va_list ap; |
238 | | |
239 | 4.02k | assert(fmt); |
240 | | |
241 | 4.02k | va_start(ap, fmt); |
242 | 4.02k | s = avahi_strdup_vprintf(fmt, ap); |
243 | 4.02k | va_end(ap); |
244 | | |
245 | 4.02k | return s; |
246 | 4.02k | } |
247 | | |
248 | 1.09k | void *avahi_memdup(const void *s, size_t l) { |
249 | 1.09k | void *p; |
250 | 1.09k | assert(s); |
251 | | |
252 | 1.09k | if (!(p = avahi_malloc(l))) |
253 | 0 | return NULL; |
254 | | |
255 | 1.09k | memcpy(p, s, l); |
256 | 1.09k | return p; |
257 | 1.09k | } |