1 /* $Id: xmalloc.c 5381 2002-03-31 22:35:47Z rra $
3 ** malloc routines with failure handling.
7 ** extern xmalloc_handler_t memory_error;
8 ** extern const char *string;
11 ** xmalloc_error_handler = memory_error;
12 ** buffer = xmalloc(1024);
13 ** xrealloc(buffer, 2048);
15 ** buffer = xcalloc(1024);
17 ** buffer = xstrdup(string);
19 ** buffer = xstrndup(string, 25);
21 ** xmalloc, xcalloc, xrealloc, and xstrdup behave exactly like their C
22 ** library counterparts without the leading x except that they will never
23 ** return NULL. Instead, on error, they call xmalloc_error_handler,
24 ** passing it the name of the function whose memory allocation failed, the
25 ** amount of the allocation, and the file and line number where the
26 ** allocation function was invoked (from __FILE__ and __LINE__). This
27 ** function may do whatever it wishes, such as some action to free up
28 ** memory or a call to sleep to hope that system resources return. If the
29 ** handler returns, the interrupted memory allocation function will try its
30 ** allocation again (calling the handler again if it still fails).
32 ** xstrndup behaves like xstrdup but only copies the given number of
33 ** characters. It allocates an additional byte over its second argument and
34 ** always nul-terminates the string.
36 ** The default error handler, if none is set by the caller, prints an error
37 ** message to stderr and exits with exit status 1. An error handler must
38 ** take a const char * (function name), size_t (bytes allocated), const
39 ** char * (file), and int (line).
41 ** xmalloc will return a pointer to a valid memory region on an xmalloc of 0
42 ** bytes, ensuring this by allocating space for one character instead of 0
45 ** The functions defined here are actually x_malloc, x_realloc, etc. The
46 ** header file defines macros named xmalloc, etc. that pass the file name
47 ** and line number to these functions.
53 #include "inn/messages.h"
56 /* The default error handler. */
58 xmalloc_fail(const char *function, size_t size, const char *file, int line)
60 sysdie("failed to %s %lu bytes at %s line %d", function,
61 (unsigned long) size, file, line);
64 /* Assign to this variable to choose a handler other than the default. */
65 xmalloc_handler_t xmalloc_error_handler = xmalloc_fail;
68 x_malloc(size_t size, const char *file, int line)
73 real_size = (size > 0) ? size : 1;
74 p = malloc(real_size);
76 (*xmalloc_error_handler)("malloc", size, file, line);
77 p = malloc(real_size);
83 x_calloc(size_t n, size_t size, const char *file, int line)
88 size = (size > 0) ? size : 1;
91 (*xmalloc_error_handler)("calloc", n * size, file, line);
98 x_realloc(void *p, size_t size, const char *file, int line)
102 newp = realloc(p, size);
103 while (newp == NULL && size > 0) {
104 (*xmalloc_error_handler)("realloc", size, file, line);
105 newp = realloc(p, size);
111 x_strdup(const char *s, const char *file, int line)
119 (*xmalloc_error_handler)("strdup", len, file, line);
127 x_strndup(const char *s, size_t size, const char *file, int line)
131 p = malloc(size + 1);
133 (*xmalloc_error_handler)("strndup", size + 1, file, line);
134 p = malloc(size + 1);