cleaned up stuff, added dht lib
[netyack.git] / src / xmalloc.c
blob2b64a41985a88b7f687f5384519560a170b95263
1 /*
2 * netyack
3 * By Daniel Borkmann <daniel@netyack.org>
4 * Copyright 2009, 2010 Daniel Borkmann.
5 * Subject to the GPL.
6 */
8 /*
9 * Copyright (C) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland,
10 * All rights reserved
11 * Copyright (C) 2010 Daniel Borkmann <daniel@netyack.org>,
12 * Ported from SSH and added several other functions and
13 * heap consistency checks
15 * Versions of malloc and friends that check their results, and never return
16 * failure (they call fatal if they encounter an error).
18 * As far as I am concerned, the code I have written for this software
19 * can be used freely for any purpose. Any derived versions of this
20 * software must be clearly marked as such, and if the derived work is
21 * incompatible with the protocol description in the RFC file, it must be
22 * called by a name other than "ssh" or "Secure Shell".
25 #define _GNU_SOURCE
26 #include <stdarg.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <mcheck.h>
31 #include <unistd.h>
32 #include <alloca.h>
33 #include <malloc.h>
35 #ifndef SIZE_T_MAX
36 # define SIZE_T_MAX ((size_t) ~0)
37 #endif
39 #include "compiler.h"
40 #include "xmalloc.h"
41 #include "strlcpy.h"
42 #include "tty.h"
43 #include "error_and_die.h"
45 __hidden void mcheck_abort(enum mcheck_status stat)
47 if (stat != MCHECK_OK)
48 error_and_die(EXIT_FAILURE, "mcheck: mem inconsistency "
49 "detected: %d\n", stat);
52 static void xmalloc_mcheck_init(void)
54 /*
55 * If we would use mcheck_pedantic() here, then libloudmouth
56 * is not able to perform SSL/TLS authentication. Weird.
58 int ret = mcheck(mcheck_abort);
59 if (ret < 0)
60 error_and_die(EXIT_FAILURE, "xmalloc: cannot init "
61 "mcheck! bug\n");
62 mtrace();
65 static void xmalloc_init_hook(void)
67 xmalloc_mcheck_init();
70 void (*__malloc_initialize_hook)(void) = xmalloc_init_hook;
72 __hidden void muntrace_handler(int signal)
74 muntrace();
75 abort();
78 __hidden int xmem_used(void)
80 struct mallinfo mi = mallinfo();
81 return mi.uordblks;
84 __hidden int xmem_free(void)
86 struct mallinfo mi = mallinfo();
87 return mi.fordblks;
90 __hidden int xmem_totalarena(void)
92 struct mallinfo mi = mallinfo();
93 return mi.arena;
96 __hidden void *xmalloc(size_t size)
98 void *ptr;
99 enum mcheck_status stat;
101 if (size == 0)
102 error_and_die(EXIT_FAILURE, "xmalloc: zero size\n");
104 ptr = malloc(size);
105 if (ptr == NULL)
106 error_and_die(EXIT_FAILURE, "xmalloc: out of memory "
107 "(allocating %lu bytes)\n", (u_long) size);
108 stat = mprobe(ptr);
109 if (stat != MCHECK_OK)
110 error_and_die(EXIT_FAILURE, "xmalloc: mem inconsistency "
111 "detected: %d\n", stat);
113 debug_blue("%p: %zu", ptr, size);
114 return ptr;
117 __hidden void *xalloca(size_t size)
119 void *ptr;
121 if (size == 0)
122 error_and_die(EXIT_FAILURE, "xalloca: zero size\n");
124 ptr = alloca(size);
125 if (ptr == NULL)
126 error_and_die(EXIT_FAILURE, "xalloca: out of memory "
127 "(allocating %lu bytes on stack)\n",
128 (u_long) size);
130 debug_blue("%p: %zu (stack)", ptr, size);
131 return ptr;
134 __hidden void *xvalloc(size_t size)
136 void *ptr;
137 enum mcheck_status stat;
139 if (size == 0)
140 error_and_die(EXIT_FAILURE, "xmalloc: zero size\n");
142 ptr = valloc(size);
143 if (ptr == NULL)
144 error_and_die(EXIT_FAILURE, "xvalloc: out of memory "
145 "(allocating %lu bytes)\n", (u_long) size);
146 stat = mprobe(ptr);
147 if (stat != MCHECK_OK)
148 error_and_die(EXIT_FAILURE, "xvalloc: mem inconsistency "
149 "detected: %d\n", stat);
151 debug_blue("%p: %zu", ptr, size);
152 return ptr;
155 __hidden void *xzmalloc(size_t size)
157 void *ptr;
158 enum mcheck_status stat;
160 if (size == 0)
161 error_and_die(EXIT_FAILURE, "xzmalloc: zero size\n");
163 ptr = malloc(size);
164 if (ptr == NULL)
165 error_and_die(EXIT_FAILURE, "xzmalloc: out of memory "
166 "(allocating %lu bytes)\n", (u_long) size);
167 stat = mprobe(ptr);
168 if (stat != MCHECK_OK)
169 error_and_die(EXIT_FAILURE, "xzmalloc: mem inconsistency "
170 "detected: %d\n", stat);
172 memset(ptr, 0, size);
174 debug_blue("%p: %zu", ptr, size);
175 return ptr;
178 __hidden void *xmalloc_aligned(size_t size, size_t alignment)
180 int ret;
181 void *ptr;
182 enum mcheck_status stat;
184 if (size == 0)
185 error_and_die(EXIT_FAILURE, "xmalloc_aligned: zero size\n");
187 ret = posix_memalign(&ptr, alignment, size);
188 if (ret != 0)
189 error_and_die(EXIT_FAILURE, "xmalloc_aligned: out of memory "
190 "(allocating %lu bytes)\n", (u_long) size);
191 stat = mprobe(ptr);
192 if (stat != MCHECK_OK)
193 error_and_die(EXIT_FAILURE, "xmalloc_aligned: mem "
194 "inconsistency detected: %d\n", stat);
196 debug_blue("%p: %zu", ptr, size);
197 return ptr;
200 __hidden void *xmallocz(size_t size)
202 void *ptr;
204 if (size + 1 < size)
205 error_and_die(EXIT_FAILURE, "xmallocz: data too large to fit "
206 "into virtual memory space\n");
208 ptr = xmalloc(size + 1);
209 ((char*) ptr)[size] = 0;
211 return ptr;
214 __hidden void *xmemdupz(const void *data, size_t len)
216 return memcpy(xmallocz(len), data, len);
219 __hidden void *xcalloc(size_t nmemb, size_t size)
221 void *ptr;
222 enum mcheck_status stat;
224 if (size == 0 || nmemb == 0)
225 error_and_die(EXIT_FAILURE, "xcalloc: zero size\n");
226 if (SIZE_T_MAX / nmemb < size)
227 error_and_die(EXIT_FAILURE, "xcalloc: nmemb * size > "
228 "SIZE_T_MAX\n");
230 ptr = calloc(nmemb, size);
231 if (ptr == NULL)
232 error_and_die(EXIT_FAILURE, "xcalloc: out of memory "
233 "(allocating %lu bytes)\n",
234 (u_long) (size * nmemb));
235 stat = mprobe(ptr);
236 if (stat != MCHECK_OK)
237 error_and_die(EXIT_FAILURE, "xcalloc: mem inconsistency "
238 "detected: %d\n", stat);
240 debug_blue("%p: %zu", ptr, size);
241 return ptr;
244 __hidden void *xrealloc(void *ptr, size_t nmemb, size_t size)
246 void *new_ptr;
247 size_t new_size = nmemb * size;
248 enum mcheck_status stat;
250 if (new_size == 0)
251 error_and_die(EXIT_FAILURE, "xrealloc: zero size\n");
252 if (SIZE_T_MAX / nmemb < size)
253 error_and_die(EXIT_FAILURE, "xrealloc: nmemb * size > "
254 "SIZE_T_MAX\n");
256 if (ptr == NULL)
257 new_ptr = malloc(new_size);
258 else
259 new_ptr = realloc(ptr, new_size);
261 if (new_ptr == NULL)
262 error_and_die(EXIT_FAILURE, "xrealloc: out of memory "
263 "(new_size %lu bytes)\n", (u_long) new_size);
264 stat = mprobe(ptr);
265 if (stat != MCHECK_OK)
266 error_and_die(EXIT_FAILURE, "xrealloc: mem inconsistency "
267 "detected: %d\n", stat);
269 debug_blue("%p: %zu => %p: %zu", ptr, size, new_ptr, new_size);
270 return new_ptr;
273 __hidden void xfree(void *ptr)
275 enum mcheck_status stat;
277 if (ptr == NULL)
278 error_and_die(EXIT_FAILURE, "xfree: NULL pointer given as "
279 "argument\n");
281 stat = mprobe(ptr);
282 if (stat != MCHECK_OK)
283 error_and_die(EXIT_FAILURE, "xfree: mem inconsistency "
284 "detected: %d\n", stat);
286 debug_blue("%p => 0", ptr);
288 free(ptr);
291 __hidden char *xstrdup(const char *str)
293 size_t len;
294 char *cp;
296 len = strlen(str) + 1;
297 cp = xmalloc(len);
298 strlcpy(cp, str, len);
300 return cp;
303 __hidden char *xstrndup(const char *str, size_t size)
305 size_t len;
306 char *cp;
308 len = strlen(str) + 1;
309 if (size < len)
310 len = size;
312 cp = xmalloc(len);
313 strlcpy(cp, str, len);
315 return cp;
318 __hidden int xdup(int fd)
320 int ret = dup(fd);
321 if (ret < 0)
322 error_and_die(EXIT_FAILURE, "xdup: dup failed\n");
324 return ret;