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