]> git.wincent.com - WOTest.git/blob - WOMalloc.c
Import WOMalloc functions from WODebug
[WOTest.git] / WOMalloc.c
1 /*
2  *  WOMalloc.c
3  *  WODebug
4  *
5  *  Created by Wincent Colaiuta on 07 February 2006.
6  *  Copyright 2006-2007 Wincent Colaiuta.
7  *
8  */
9
10 #include "WOMalloc.h"
11
12 #ifndef _STRING_H_
13 #include <string.h>
14 #endif
15
16 #ifndef _SYS_ERRNO_H_
17 #include <errno.h>
18 #endif
19
20 #ifndef _STDARG_H
21 #include <stdarg.h>
22 #endif
23
24 #if !defined(TRUE)
25 #define TRUE    1
26 #endif
27
28 #if !defined(FALSE)
29 #define FALSE   0
30 #endif
31
32 _Bool WOMallocShouldFail(void);
33
34 _Bool WOMallocShouldFail()
35 {
36     // check "always fail" environment variable
37     const char *alwaysFail = (const char *)getenv("WOMallocFailAlways");
38     if ((alwaysFail != NULL) && (strcmp(alwaysFail, "1") == 0))
39         return TRUE;
40
41     // check "fail randomly" environment variable
42     const char *randomly = (const char *)getenv("WOMallocFailRandomly");
43     if (randomly != NULL)
44     {
45         // try to extract double value between 0 and 1 from environment variable
46         double probability = strtod(randomly, (char **)NULL); // ignore errors
47
48         // impose range limits
49         if (probability <= 0) return FALSE;  // don't force failure
50         if (probability >= 1) return TRUE;   // do force failure
51
52         // given probability, decide whether or not to fail
53         // get value between 0 and 0xfffffffe (2 to the power of 31, minus 1)
54         if (random() < (probability * 0xfffffffe))
55             return TRUE;
56     }
57
58     return FALSE; // fallback case: don't force failure
59 }
60
61 #pragma mark -
62 #pragma mark Base wrapper functions
63
64 void * WOMalloc(size_t size)
65 {
66     if (WOMallocShouldFail())
67     {
68         errno = ENOMEM;
69         return NULL;
70     }
71
72     return malloc(size);
73 }
74
75 void * WOCalloc(size_t count, size_t size)
76 {
77     if (WOMallocShouldFail())
78     {
79         errno = ENOMEM;
80         return NULL;
81     }
82
83     return calloc(count, size);
84 }
85
86 void * WOValloc(size_t size)
87 {
88     if (WOMallocShouldFail())
89     {
90         errno = ENOMEM;
91         return NULL;
92     }
93
94     return valloc(size);
95 }
96
97 void * WORealloc(void *ptr, size_t size)
98 {
99     if (WOMallocShouldFail())
100     {
101         errno = ENOMEM;
102         return NULL;
103     }
104
105     return realloc(ptr, size);
106 }
107
108 void * WOReallocf(void *ptr, size_t size)
109 {
110     if (WOMallocShouldFail())
111     {
112         errno = ENOMEM;
113         return NULL;
114     }
115
116     return reallocf(ptr, size);
117 }
118
119 #pragma mark -
120 #pragma mark Wrapper functions with forced failure control
121
122 void * WOMallocFail(size_t size, _Bool fail)
123 {
124     if (fail)
125     {
126         errno = ENOMEM;
127         return NULL;
128     }
129
130     return malloc(size);
131 }
132
133 void * WOCallocFail(size_t count, size_t size, _Bool fail)
134 {
135     if (fail)
136     {
137         errno = ENOMEM;
138         return NULL;
139     }
140
141     return calloc(count, size);
142 }
143
144 void * WOVallocFail(size_t size, _Bool fail)
145 {
146     if (fail)
147     {
148         errno = ENOMEM;
149         return NULL;
150     }
151
152     return valloc(size);
153 }
154
155 void * WOReallocFail(void *ptr, size_t size, _Bool fail)
156 {
157     if (fail)
158     {
159         errno = ENOMEM;
160         return NULL;
161     }
162
163     return realloc(ptr, size);
164 }
165
166 void * WOReallocfFail(void *ptr, size_t size, _Bool fail)
167 {
168     if (fail)
169     {
170         errno = ENOMEM;
171         return NULL;
172     }
173
174     return reallocf(ptr, size);
175 }
176
177 #pragma mark -
178 #pragma mark Variadic helper functions
179
180 void * WOMallocFailv(size_t size, ...)
181 {
182     va_list args;
183     va_start(args, size);
184     int   fail            = FALSE;
185     void    *returnValue    = NULL;
186
187     // get optional failure flag, if present
188     if ((fail = va_arg(args, int)))
189         returnValue = WOMallocFail(size, fail); // use forced failure version
190     else
191         returnValue = WOMalloc(size);           // use standard version
192
193     va_end(args);
194     return returnValue;
195 }
196
197 void * WOCallocFailv(size_t count, size_t size, ...)
198 {
199     va_list args;
200     va_start(args, size);
201     int   fail            = FALSE;
202     void    *returnValue    = NULL;
203
204     // get optional failure flag, if present
205     if ((fail = va_arg(args, int)))
206         returnValue = WOCallocFail(count, size, fail);
207     else
208         returnValue = WOCalloc(count, size);
209
210     va_end(args);
211     return returnValue;
212 }
213
214 void * WOVallocFailv(size_t size, ...)
215 {
216     va_list args;
217     va_start(args, size);
218     int   fail            = FALSE;
219     void    *returnValue    = NULL;
220
221     // get optional failure flag, if present
222     if ((fail = va_arg(args, int)))
223         returnValue = WOVallocFail(size, fail);
224     else
225         returnValue = WOValloc(size);
226
227     va_end(args);
228     return returnValue;
229 }
230
231 void * WOReallocFailv(void *ptr, size_t size, ...)
232 {
233     va_list args;
234     va_start(args, size);
235     int   fail            = FALSE;
236     void    *returnValue    = NULL;
237
238     // get optional failure flag, if present
239     if ((fail = va_arg(args, int)))
240         returnValue = WOReallocFail(ptr, size, fail);
241     else
242         returnValue = WORealloc(ptr, size);
243
244     va_end(args);
245     return returnValue;
246 }
247
248 void * WOReallocfFailv(void *ptr, size_t size, ...)
249 {
250     va_list args;
251     va_start(args, size);
252     int   fail            = FALSE;
253     void    *returnValue    = NULL;
254
255     // get optional failure flag, if present
256     if ((fail = va_arg(args, int)))
257         returnValue = WOReallocfFail(ptr, size, fail);
258     else
259         returnValue = WOReallocf(ptr, size);
260
261     va_end(args);
262     return returnValue;
263 }