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  |