1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2016, Olivier MATZ <zer0@droids-corp.org>
6 * Interface to configure the allocator used by libecoli.
7 * By default, the standard allocation functions from libc are used.
13 #include <sys/types.h>
18 * Function type of malloc, passed to ec_malloc_register().
20 * The API is the same than malloc(), excepted the file and line
24 * The size of the memory area to allocate.
26 * The path to the file that invoked the malloc.
28 * The line in the file that invoked the malloc.
30 * A pointer to the allocated memory area, or NULL on error (errno
33 typedef void *(*ec_malloc_t)(size_t size, const char *file, unsigned int line);
36 * Function type of free, passed to ec_malloc_register().
38 * The API is the same than free(), excepted the file and line
42 * The pointer to the memory area to be freed.
44 * The path to the file that invoked the malloc.
46 * The line in the file that invoked the malloc.
48 typedef void (*ec_free_t)(void *ptr, const char *file, unsigned int line);
51 * Function type of realloc, passed to ec_malloc_register().
53 * The API is the same than realloc(), excepted the file and line
57 * The pointer to the memory area to be reallocated.
59 * The path to the file that invoked the malloc.
61 * The line in the file that invoked the malloc.
63 * A pointer to the allocated memory area, or NULL on error (errno
66 typedef void *(*ec_realloc_t)(void *ptr, size_t size, const char *file,
70 * Register allocation functions.
72 * This function can be use to register another allocator
73 * to be used by libecoli. By default, ec_malloc(), ec_free() and
74 * ec_realloc() use the standard libc allocator. Another handler
75 * can be used for debug purposes or when running in a specific
78 * This function must be called before ec_init().
81 * A user-defined malloc function.
83 * A user-defined free function.
85 * A user-defined realloc function.
87 * 0 on success, or -1 on error (errno is set).
89 int ec_malloc_register(ec_malloc_t usr_malloc, ec_free_t usr_free,
90 ec_realloc_t usr_realloc);
92 struct ec_malloc_handler {
98 extern struct ec_malloc_handler ec_malloc_handler;
101 * Allocate a memory area.
103 * Like malloc(), ec_malloc() allocates size bytes and returns a pointer
104 * to the allocated memory. The memory is not initialized. The memory is
105 * freed with ec_free().
108 * The size of the area to allocate in bytes.
110 * The pointer to the allocated memory, or NULL on error (errno is set).
112 #define ec_malloc(size) ({ \
114 if (ec_malloc_handler.malloc == NULL) \
115 ret_ = malloc(size); \
117 ret_ = __ec_malloc(size, __FILE__, __LINE__); \
122 * Ecoli malloc function.
124 * Use this function when the macro ec_malloc() cannot be used,
125 * for instance when it is passed as a callback pointer.
127 void *ec_malloc_func(size_t size);
130 * Free a memory area.
132 * Like free(), ec_free() frees the area pointed by ptr, which must have
133 * been returned by a previous call to ec_malloc() or any other
134 * allocation function of this file.
137 * The pointer to the memory area.
139 #define ec_free(ptr) ({ \
140 if (ec_malloc_handler.free == NULL) \
143 __ec_free(ptr, __FILE__, __LINE__); \
147 * Ecoli free function.
149 * Use this function when the macro ec_free() cannot be used,
150 * for instance when it is passed as a callback pointer.
152 void ec_free_func(void *ptr);
155 * Resize an allocated memory area.
158 * The pointer to the previously allocated memory area, or NULL.
160 * The new size of the memory area.
162 * A pointer to the newly allocated memory, or NULL if the request
163 * fails. In that case, the original area is left untouched.
165 #define ec_realloc(ptr, size) ({ \
167 if (ec_malloc_handler.realloc == NULL) \
168 ret_ = realloc(ptr, size); \
170 ret_ = __ec_realloc(ptr, size, __FILE__, __LINE__); \
175 * Allocate and initialize an array of elements.
178 * The number of elements.
180 * The size of each element.
182 * The pointer to the allocated memory, or NULL on error (errno is set).
184 #define ec_calloc(n, size) ({ \
186 if (ec_malloc_handler.malloc == NULL) \
187 ret_ = calloc(n, size); \
189 ret_ = __ec_calloc(n, size, __FILE__, __LINE__); \
194 * Duplicate a string.
196 * Memory for the new string is obtained with ec_malloc(), and can be
197 * freed with ec_free().
200 * The string to be duplicated.
202 * The pointer to the duplicated string, or NULL on error (errno is set).
204 #define ec_strdup(s) ({ \
206 if (ec_malloc_handler.malloc == NULL) \
209 ret_ = __ec_strdup(s, __FILE__, __LINE__); \
214 * Duplicate at most n bytes of a string.
216 * This function is similar to ec_strdup(), except that it copies at
217 * most n bytes. If s is longer than n, only n bytes are copied, and a
218 * terminating null byte ('\0') is added.
221 * The string to be duplicated.
223 * The maximum length of the new string.
225 * The pointer to the duplicated string, or NULL on error (errno is set).
227 #define ec_strndup(s, n) ({ \
229 if (ec_malloc_handler.malloc == NULL) \
230 ret_ = strndup(s, n); \
232 ret_ = __ec_strndup(s, n, __FILE__, __LINE__); \
237 void *__ec_malloc(size_t size, const char *file, unsigned int line);
238 void __ec_free(void *ptr, const char *file, unsigned int line);
239 void *__ec_calloc(size_t nmemb, size_t size, const char *file,
241 void *__ec_realloc(void *ptr, size_t size, const char *file, unsigned int line);
242 char *__ec_strdup(const char *s, const char *file, unsigned int line);
243 char *__ec_strndup(const char *s, size_t n, const char *file,