1    | /***************************************
2    |   $Revision: 1.15 $
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,2000,2001,2002               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 "rip.h"
34   | #include <stdlib.h>
35   | #include <glib.h>
36   | 
37   | /* undefine our wrappers so we can use the real functions */
38   | #undef UT_malloc
39   | #undef UT_calloc
40   | #undef UT_realloc
41   | #undef UT_free
42   | #undef UT_strdup
43   | #undef wr_malloc
44   | #undef wr_calloc
45   | #undef wr_realloc
46   | #undef wr_free
47   | #undef wr_string
48   | #undef wr_clear_list
49   | 
50   | 
51   | #define USE_LOGGING
52   | 
53   | #ifdef USE_LOGGING
54   | /* flag whether logging now active */
55   | static int UT_memory_logging = 0;
56   | 
57   | void 
58   | UT_memory_log (int active) 
59   | {
60   |     if (active) {
61   |         UT_memory_logging = 1;
62   |     } else {
63   |         UT_memory_logging = 0;
64   |     }
65   | }
66   | 
67   | static void
68   | UT_alloc_log (const void *ptr, int len, const char* file, int line) 
69   | {
70   |     if (UT_memory_logging) {
71   |         ER_dbg_va(FAC_UT, ASP_UT_MEM, 
72   | 	    "%020p <- allocated %d bytes [%s:%d]",
73   | 	    ptr, len, file, line);
74   |     }
75   | }
76   | 
77   | static void
78   | UT_free_log (const void *ptr, const char* file, int line) 
79   | {
80   |     if (UT_memory_logging) {
81   |         ER_dbg_va(FAC_UT, ASP_UT_MEM, 
82   | 	    "%020p -> freed [%s:%d]",
83   | 	    ptr, file, line); 
84   |     }
85   | }
86   | 
87   | #else
88   | 
89   | void 
90   | UT_memory_log (int active)
91   | {
92   |     ER_perror(FAC_UT, UT_NOMEMLOG, 
93   |         "logging not supported, recompile %s to enable", __FILE__);
94   | }
95   | 
96   | /* if logging is disabled, then these functions are NOOP's */
97   | #define UT_alloc_log(ptr,len,file,line)
98   | #define UT_free_log(ptr,file,line) 
99   | #define UT_free_list_log(ptr,file,line) 
100  | 
101  | #endif /* USE_LOGGING */
102  | 
103  | void *
104  | UT_malloc_real (size_t size, const char *file, int line)
105  | {
106  |     void *ptr;
107  | 
108  |     ptr = malloc(size);
109  |     if (ptr == NULL) {
110  |         ER_perror(FAC_UT, UT_OUTMEM, 
111  |             "malloc(%u) out of memory at %s:%d", size, file, line);
112  |         die;
113  |     }
114  |     UT_alloc_log(ptr, size, file, line); 
115  |     return ptr;
116  | }
117  | 
118  | void *
119  | UT_calloc_real (size_t num, size_t size, const char *file, int line)
120  | {
121  |     void *ptr;
122  | 
123  |     ptr = calloc(num, size);
124  |     if (ptr == NULL) {
125  |         ER_perror(FAC_UT, UT_OUTMEM, 
126  |             "calloc(%u, %u) out of memory at %s:%d", num, size, file, line);
127  |         die; 
128  |     }
129  |     UT_alloc_log(ptr, size * num, file, line);
130  |     return ptr;
131  | }
132  | 
133  | void *
134  | UT_realloc_real (void *ptr, size_t size, const char *file, int line)
135  | {
136  |     char *tmp_ptr;
137  |     
138  |     tmp_ptr = realloc(ptr, size);
139  |     if (tmp_ptr == NULL ) {
140  |         ER_perror(FAC_UT, UT_OUTMEM, 
141  |             "realloc(%p, %u) out of memory at %s:%d", ptr, size, file, line);
142  |         die; 
143  |     } 
144  |     UT_free_log(ptr, file, line);
145  |     UT_alloc_log(tmp_ptr, size, file, line);
146  |     return tmp_ptr;
147  | }
148  | 
149  | void 
150  | UT_free_real (void *ptr, const char *file, int line)
151  | {
152  |     free(ptr);
153  |     UT_free_log(ptr, file, line); 
154  | }
155  | 
156  | char *
157  | UT_strdup_real (const char *str, const char *file, int line)
158  | {
159  |     char *area;
160  | 
161  |     area = UT_malloc_real(strlen(str) + 1, file, line);
162  |     strcpy(area, str);
163  |     
164  |     return area;
165  | }
166  | 
167  | 
168  | /* legacy functions */
169  | 
170  | void 
171  | wr_log_set (int value) 
172  | {
173  |     UT_memory_log(value);
174  | }
175  | 
176  | er_ret_t 
177  | wr_real_malloc (void **ptr, size_t size, const char* file, int line) 
178  | {
179  |     *ptr = UT_malloc_real(size, file, line);
180  |     return UT_OK;
181  | }
182  | 
183  | er_ret_t 
184  | wr_real_calloc (void **ptr, size_t num, size_t size, const char* file, 
185  |                 int line) 
186  | {
187  |     *ptr = UT_calloc_real(num, size, file, line);
188  |     return UT_OK;
189  | }
190  | 
191  | 
192  | er_ret_t  
193  | wr_real_realloc (void **ptr, size_t size, const char* file, int line) 
194  | {
195  |     *ptr = UT_realloc_real(*ptr, size, file, line);
196  |     return UT_OK;
197  | }
198  | 
199  | er_ret_t 
200  | wr_real_free (void *ptr, const char* file, int line) 
201  | {
202  |     UT_free_real(ptr, file, line);
203  |     return UT_OK;
204  | }
205  | 
206  | 
207  | /* make a copy and return the pointer to the allocated area, like strdup() */
208  | char *
209  | wr_real_string (const char *text, const char *file, int line)
210  | {
211  |     return UT_strdup_real(text, file, line);
212  | }
213  | 
214  | /* for GList's foreach */
215  | static
216  | void
217  | wr_free_list_element (void *cpy, void *trash)
218  | {
219  |     wr_real_free(cpy, __FILE__, __LINE__);
220  | }
221  | 
222  | /* for GList's foreach */
223  | void
224  | wr_real_clear_list (GList **list, const char* file, int line)
225  | {
226  |     /* allow NULL argument */
227  |     if( *list != NULL ) {
228  | 	g_list_foreach(*list, wr_free_list_element, NULL);
229  | 	g_list_free(*list);
230  | 	*list = NULL;
231  |     }
232  | }
233  |