1 /* $Id: xmalloc.c 5379 2002-03-31 21:45:12Z rra $ */
2 /* Test suite for xmalloc and family. */
10 /* Linux requires sys/time.h be included before sys/resource.h. */
12 # include <sys/time.h>
14 #include <sys/resource.h>
16 #include "inn/messages.h"
19 /* A customized error handler for checking xmalloc's support of them.
20 Prints out the error message and exits with status 1. */
22 test_handler(const char *function, size_t size, const char *file, int line)
24 die("%s %lu %s %d", function, (unsigned long) size, file, line);
27 /* Allocate the amount of memory given and write to all of it to make sure
28 we can, returning true if that succeeded and false on any sort of
31 test_malloc(size_t size)
36 buffer = xmalloc(size);
40 memset(buffer, 1, size);
41 for (i = 0; i < size; i++)
48 /* Allocate half the memory given, write to it, then reallocate to the
49 desired size, writing to the rest and then checking it all. Returns true
50 on success, false on any failure. */
52 test_realloc(size_t size)
57 buffer = xmalloc(size / 2);
61 memset(buffer, 1, size / 2);
62 buffer = xrealloc(buffer, size);
66 memset(buffer + size / 2, 2, size - size / 2);
67 for (i = 0; i < size / 2; i++)
70 for (i = size / 2; i < size; i++)
77 /* Generate a string of the size indicated, call xstrdup on it, and then
78 ensure the result matches. Returns true on success, false on any
81 test_strdup(size_t size)
86 string = xmalloc(size);
89 memset(string, 1, size - 1);
90 string[size - 1] = '\0';
91 copy = xstrdup(string);
94 match = strcmp(string, copy);
100 /* Generate a string of the size indicated plus some, call xstrndup on it, and
101 then ensure the result matches. Returns true on success, false on any
104 test_strndup(size_t size)
109 string = xmalloc(size + 1);
112 memset(string, 1, size - 1);
113 string[size - 1] = 2;
115 copy = xstrndup(string, size - 1);
118 match = strncmp(string, copy, size - 1);
119 toomuch = strcmp(string, copy);
122 return (match == 0 && toomuch != 0);
125 /* Allocate the amount of memory given and check that it's all zeroed,
126 returning true if that succeeded and false on any sort of detectable
129 test_calloc(size_t size)
135 if (nelems * 4 != size)
137 buffer = xcalloc(nelems, 4);
140 for (i = 0; i < size; i++)
147 /* Take the amount of memory to allocate in bytes as a command-line argument
148 and call test_malloc with that amount of memory. */
150 main(int argc, char *argv[])
159 die("Usage error. Type, size, and limit must be given.");
161 size = strtol(argv[2], 0, 10);
162 if (size == 0 && errno != 0)
163 sysdie("Invalid size");
165 limit = strtol(argv[3], 0, 10);
166 if (limit == 0 && errno != 0)
167 sysdie("Invalid limit");
169 /* If a memory limit was given and we can set memory limits, set it.
170 Otherwise, exit 2, signalling to the driver that the test should be
171 skipped. We do this here rather than in the driver due to some
172 pathological problems with Linux (setting ulimit in the shell caused
173 the shell to die). */
175 #if HAVE_SETRLIMIT && defined(RLIMIT_DATA)
178 if (setrlimit(RLIMIT_DATA, &rl) < 0) {
179 syswarn("Can't set data limit to %lu", (unsigned long) limit);
183 warn("Data limits aren't supported.");
188 /* If the code is capitalized, install our customized error handler. */
191 xmalloc_error_handler = test_handler;
192 code = tolower(code);
195 /* Decide if the allocation should fail. If it should, set willfail to
196 2, so that if it unexpectedly succeeds, we exit with a status
197 indicating that the test should be skipped. */
199 if (code == 's' || code == 'n')
201 if (limit > 0 && max > limit)
205 case 'c': exit(test_calloc(size) ? willfail : 1);
206 case 'm': exit(test_malloc(size) ? willfail : 1);
207 case 'r': exit(test_realloc(size) ? willfail : 1);
208 case 's': exit(test_strdup(size) ? willfail : 1);
209 case 'n': exit(test_strndup(size) ? willfail : 1);
211 die("Unknown mode %c", argv[1][0]);