1 | /***************************************
2 | $Revision: 1.11 $
3 |
4 | Utilities (ut). memwrap.c - memory allocation wrappers.
5 | Facilitate easy changing a memory allocation
6 | library and provide uniform error codes.
7 |
8 | Status: NOT REVUED, TESTED,
9 |
10 | Design and implementation by: Marek Bukowy
11 |
12 | ******************/ /******************
13 | Copyright (c) 1999 RIPE NCC
14 |
15 | All Rights Reserved
16 |
17 | Permission to use, copy, modify, and distribute this software and its
18 | documentation for any purpose and without fee is hereby granted,
19 | provided that the above copyright notice appear in all copies and that
20 | both that copyright notice and this permission notice appear in
21 | supporting documentation, and that the name of the author not be
22 | used in advertising or publicity pertaining to distribution of the
23 | software without specific, written prior permission.
24 |
25 | THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
26 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
27 | AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
28 | DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
29 | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
30 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
31 | ***************************************/
32 |
33 | #include <stdlib.h>
34 | #include <erroutines.h>
35 | #include <stubs.h>
36 | #include <glib.h>
37 |
38 | #define USE_LOGGING
39 |
40 | #ifdef USE_LOGGING
41 | /* flag whether logging now active */
42 | static int UT_memory_logging = 0;
43 |
44 | void
45 | UT_memory_log (int active)
46 | {
47 | if (active) {
48 | UT_memory_logging = 1;
49 | } else {
50 | UT_memory_logging = 0;
51 | }
52 | }
53 |
54 | static void
55 | UT_alloc_log (const void *ptr, int len, const char* file, int line)
56 | {
57 | if (UT_memory_logging) {
58 | ER_dbg_va(FAC_UT, ASP_UT_MEM,
59 | "allocated %d bytes at address %p in %s:%d",
60 | len, ptr, file, line);
61 | }
62 | }
63 |
64 | static void
65 | UT_free_log (const void *ptr, const char* file, int line)
66 | {
67 | if (UT_memory_logging) {
68 | ER_dbg_va(FAC_UT, ASP_UT_MEM,
69 | "freed memory at address %p in %s:%d",
70 | ptr, file, line);
71 | }
72 | }
73 |
74 | static void
75 | wr_free_list_log (const void *ptr, const char* file, int line)
76 | {
77 | if (UT_memory_logging) {
78 | ER_dbg_va(FAC_UT, ASP_UT_MEM,
79 | "freeing list and elements at address %p in %s:%d",
80 | ptr, file, line);
81 | }
82 | }
83 | #else
84 |
85 | void
86 | UT_memory_log (int active)
87 | {
88 | ER_perror(FAC_UT, UT_NOMEMLOG,
89 | "logging not supported, recompile %s to enable", __FILE__);
90 | }
91 |
92 | /* if logging is disabled, then these functions are NOOP's */
93 | #define UT_alloc_log(ptr,len,file,line)
94 | #define UT_free_log(ptr,file,line)
95 | #define UT_free_list_log(ptr,file,line)
96 |
97 | #endif /* USE_LOGGING */
98 |
99 | void *
100 | UT_malloc_real (size_t size, const char *file, int line)
101 | {
102 | void *ptr;
103 |
104 | ptr = malloc(size);
105 | if (ptr == NULL) {
106 | ER_perror(FAC_UT, UT_OUTMEM,
107 | "malloc(%u) out of memory at %s:%d", size, file, line);
108 | die;
109 | }
110 | UT_alloc_log(ptr, size, file, line);
111 | return ptr;
112 | }
113 |
114 | void *
115 | UT_calloc_real (size_t num, size_t size, const char *file, int line)
116 | {
117 | void *ptr;
118 |
119 | ptr = calloc(num, size);
120 | if (ptr == NULL) {
121 | ER_perror(FAC_UT, UT_OUTMEM,
122 | "calloc(%u, %u) out of memory at %s:%d", num, size, file, line);
123 | die;
124 | }
125 | UT_alloc_log(ptr, size * num, file, line);
126 | return ptr;
127 | }
128 |
129 | void *
130 | UT_realloc_real (void *ptr, size_t size, const char *file, int line)
131 | {
132 | char *tmp_ptr;
133 |
134 | tmp_ptr = realloc(ptr, size);
135 | if (tmp_ptr == NULL ) {
136 | ER_perror(FAC_UT, UT_OUTMEM,
137 | "realloc(%p, %u) out of memory at %s:%d", ptr, size, file, line);
138 | die;
139 | }
140 | UT_free_log(ptr, file, line);
141 | UT_alloc_log(tmp_ptr, size, file, line);
142 | return tmp_ptr;
143 | }
144 |
145 | void
146 | UT_free_real (void *ptr, const char *file, int line)
147 | {
148 | dieif(ptr == NULL);
149 | free(ptr);
150 | UT_free_log(ptr, file, line);
151 | }
152 |
153 | char *
154 | UT_strdup_real (const char *str, const char *file, int line)
155 | {
156 | char *area;
157 |
158 | area = UT_malloc_real(strlen(str) + 1, file, line);
159 | strcpy(area, str);
160 |
161 | return area;
162 | }
163 |
164 |
165 | /* legacy functions */
166 |
167 | void
168 | wr_log_set (int value)
169 | {
170 | UT_memory_log(value);
171 | }
172 |
173 | er_ret_t
174 | wr_real_malloc (void **ptr, size_t size, const char* file, int line)
175 | {
176 | *ptr = UT_malloc_real(size, file, line);
177 | return UT_OK;
178 | }
179 |
180 | er_ret_t
181 | wr_real_calloc (void **ptr, size_t num, size_t size, const char* file,
182 | int line)
183 | {
184 | *ptr = UT_calloc_real(num, size, file, line);
185 | return UT_OK;
186 | }
187 |
188 |
189 | er_ret_t
190 | wr_real_realloc (void **ptr, size_t size, const char* file, int line)
191 | {
192 | *ptr = UT_realloc_real(*ptr, size, file, line);
193 | return UT_OK;
194 | }
195 |
196 | er_ret_t
197 | wr_real_free (void *ptr, const char* file, int line)
198 | {
199 | UT_free_real(ptr, file, line);
200 | return UT_OK;
201 | }
202 |
203 |
204 | /* make a copy and return the pointer to the allocated area, like strdup() */
205 | char *
206 | wr_real_string (const char *text, const char *file, int line)
207 | {
208 | return UT_strdup_real(text, file, line);
209 | }
210 |
211 | /* for GList's foreach */
212 | static
213 | void
214 | wr_free_list_element (void *cpy, void *trash)
215 | {
216 | wr_real_free(cpy, __FILE__, __LINE__);
217 | }
218 |
219 | /* for GList's foreach */
220 | void
221 | wr_real_clear_list (GList **list, const char* file, int line)
222 | {
223 | /* allow NULL argument */
224 | if( *list != NULL ) {
225 | wr_free_list_log(*list, file, line);
226 | g_list_foreach(*list, wr_free_list_element, NULL);
227 | g_list_free(*list);
228 | *list = NULL;
229 | }
230 | }
231 |