cb550fb0bc19ebb409b1109f8513ad65383082da
[protos/libecoli.git] / lib / ecoli_malloc.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2016, Olivier MATZ <zer0@droids-corp.org>
3  */
4
5 #include <ecoli_init.h>
6 #include <ecoli_malloc.h>
7
8 #include <stdlib.h>
9 #include <string.h>
10 #include <errno.h>
11
12 static int init_done = 0;
13
14 struct ec_malloc_handler ec_malloc_handler;
15
16 int ec_malloc_register(ec_malloc_t usr_malloc, ec_free_t usr_free,
17         ec_realloc_t usr_realloc)
18 {
19         if (usr_malloc == NULL || usr_free == NULL || usr_realloc == NULL) {
20                 errno = EINVAL;
21                 return -1;
22         }
23
24         if (init_done) {
25                 errno = EBUSY;
26                 return -1;
27         }
28
29         ec_malloc_handler.malloc = usr_malloc;
30         ec_malloc_handler.free = usr_free;
31         ec_malloc_handler.realloc = usr_realloc;
32
33         return 0;
34 }
35
36 void *__ec_malloc(size_t size, const char *file, unsigned int line)
37 {
38         return ec_malloc_handler.malloc(size, file, line);
39 }
40
41 void *ec_malloc_func(size_t size)
42 {
43         return __ec_malloc(size, __FILE__, __LINE__);
44 }
45
46 void __ec_free(void *ptr, const char *file, unsigned int line)
47 {
48         ec_malloc_handler.free(ptr, file, line);
49 }
50
51 void ec_free_func(void *ptr)
52 {
53         __ec_free(ptr, __FILE__, __LINE__);
54 }
55
56 void *__ec_calloc(size_t nmemb, size_t size, const char *file,
57         unsigned int line)
58 {
59         void *ptr;
60         size_t total;
61
62         /* check overflow */
63         total = size * nmemb;
64         if (nmemb != 0 && size != (total / nmemb)) {
65                 errno = ENOMEM;
66                 return NULL;
67         }
68
69         ptr = __ec_malloc(total, file, line);
70         if (ptr == NULL)
71                 return NULL;
72
73         memset(ptr, 0, total);
74         return ptr;
75 }
76
77 void *__ec_realloc(void *ptr, size_t size, const char *file, unsigned int line)
78 {
79         return ec_malloc_handler.realloc(ptr, size, file, line);
80 }
81
82 char *__ec_strdup(const char *s, const char *file, unsigned int line)
83 {
84         size_t sz = strlen(s) + 1;
85         char *s2;
86
87         s2 = __ec_malloc(sz, file, line);
88         if (s2 == NULL)
89                 return NULL;
90
91         memcpy(s2, s, sz);
92
93         return s2;
94 }
95
96 char *__ec_strndup(const char *s, size_t n, const char *file, unsigned int line)
97 {
98         size_t sz = strnlen(s, n);
99         char *s2;
100
101         s2 = __ec_malloc(sz + 1, file, line);
102         if (s2 == NULL)
103                 return NULL;
104
105         memcpy(s2, s, sz);
106         s2[sz] = '\0';
107
108         return s2;
109 }
110
111 static int ec_malloc_init_func(void)
112 {
113         init_done = 1;
114         return 0;
115 }
116
117 static struct ec_init ec_malloc_init = {
118         .init = ec_malloc_init_func,
119         .priority = 50,
120 };
121
122 EC_INIT_REGISTER(ec_malloc_init);