1 | /***************************************
2 | $Revision: 1.13 $
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 | "%020p <- allocated %d bytes [%s:%d]",
60 | ptr, len, 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 | "%020p -> freed [%s:%d]",
70 | ptr, file, line);
71 | }
72 | }
73 |
74 | #else
75 |
76 | void
77 | UT_memory_log (int active)
78 | {
79 | ER_perror(FAC_UT, UT_NOMEMLOG,
80 | "logging not supported, recompile %s to enable", __FILE__);
81 | }
82 |
83 | /* if logging is disabled, then these functions are NOOP's */
84 | #define UT_alloc_log(ptr,len,file,line)
85 | #define UT_free_log(ptr,file,line)
86 | #define UT_free_list_log(ptr,file,line)
87 |
88 | #endif /* USE_LOGGING */
89 |
90 | void *
91 | UT_malloc_real (size_t size, const char *file, int line)
92 | {
93 | void *ptr;
94 |
95 | ptr = malloc(size);
96 | if (ptr == NULL) {
97 | ER_perror(FAC_UT, UT_OUTMEM,
98 | "malloc(%u) out of memory at %s:%d", size, file, line);
99 | die;
100 | }
101 | UT_alloc_log(ptr, size, file, line);
102 | return ptr;
103 | }
104 |
105 | void *
106 | UT_calloc_real (size_t num, size_t size, const char *file, int line)
107 | {
108 | void *ptr;
109 |
110 | ptr = calloc(num, size);
111 | if (ptr == NULL) {
112 | ER_perror(FAC_UT, UT_OUTMEM,
113 | "calloc(%u, %u) out of memory at %s:%d", num, size, file, line);
114 | die;
115 | }
116 | UT_alloc_log(ptr, size * num, file, line);
117 | return ptr;
118 | }
119 |
120 | void *
121 | UT_realloc_real (void *ptr, size_t size, const char *file, int line)
122 | {
123 | char *tmp_ptr;
124 |
125 | tmp_ptr = realloc(ptr, size);
126 | if (tmp_ptr == NULL ) {
127 | ER_perror(FAC_UT, UT_OUTMEM,
128 | "realloc(%p, %u) out of memory at %s:%d", ptr, size, file, line);
129 | die;
130 | }
131 | UT_free_log(ptr, file, line);
132 | UT_alloc_log(tmp_ptr, size, file, line);
133 | return tmp_ptr;
134 | }
135 |
136 | void
137 | UT_free_real (void *ptr, const char *file, int line)
138 | {
139 | free(ptr);
140 | UT_free_log(ptr, file, line);
141 | }
142 |
143 | char *
144 | UT_strdup_real (const char *str, const char *file, int line)
145 | {
146 | char *area;
147 |
148 | area = UT_malloc_real(strlen(str) + 1, file, line);
149 | strcpy(area, str);
150 |
151 | return area;
152 | }
153 |
154 |
155 | /* legacy functions */
156 |
157 | void
158 | wr_log_set (int value)
159 | {
160 | UT_memory_log(value);
161 | }
162 |
163 | er_ret_t
164 | wr_real_malloc (void **ptr, size_t size, const char* file, int line)
165 | {
166 | *ptr = UT_malloc_real(size, file, line);
167 | return UT_OK;
168 | }
169 |
170 | er_ret_t
171 | wr_real_calloc (void **ptr, size_t num, size_t size, const char* file,
172 | int line)
173 | {
174 | *ptr = UT_calloc_real(num, size, file, line);
175 | return UT_OK;
176 | }
177 |
178 |
179 | er_ret_t
180 | wr_real_realloc (void **ptr, size_t size, const char* file, int line)
181 | {
182 | *ptr = UT_realloc_real(*ptr, size, file, line);
183 | return UT_OK;
184 | }
185 |
186 | er_ret_t
187 | wr_real_free (void *ptr, const char* file, int line)
188 | {
189 | UT_free_real(ptr, file, line);
190 | return UT_OK;
191 | }
192 |
193 |
194 | /* make a copy and return the pointer to the allocated area, like strdup() */
195 | char *
196 | wr_real_string (const char *text, const char *file, int line)
197 | {
198 | return UT_strdup_real(text, file, line);
199 | }
200 |
201 | /* for GList's foreach */
202 | static
203 | void
204 | wr_free_list_element (void *cpy, void *trash)
205 | {
206 | wr_real_free(cpy, __FILE__, __LINE__);
207 | }
208 |
209 | /* for GList's foreach */
210 | void
211 | wr_real_clear_list (GList **list, const char* file, int line)
212 | {
213 | /* allow NULL argument */
214 | if( *list != NULL ) {
215 | g_list_foreach(*list, wr_free_list_element, NULL);
216 | g_list_free(*list);
217 | *list = NULL;
218 | }
219 | }
220 |