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 |