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 |