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  |