source: roaraudio/libroar/memmgr.c @ 4972:4341665f3041

Last change on this file since 4972:4341665f3041 was 4972:4341665f3041, checked in by phi, 13 years ago

detect changes in null-buffer on several memmgr calls

File size: 5.3 KB
Line 
1//memmgr.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2011
5 *
6 *  This file is part of libroar a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  libroar is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 *  NOTE for everyone want's to change something and send patches:
25 *  read README and HACKING! There a addition information on
26 *  the license of this document you need to read before you send
27 *  any patches.
28 *
29 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
30 *  or libpulse*:
31 *  The libs libroaresd, libroararts and libroarpulse link this lib
32 *  and are therefore GPL. Because of this it may be illigal to use
33 *  them with any software that uses libesd, libartsc or libpulse*.
34 */
35
36#include "libroar.h"
37
38#define NULL_BUFFER_CONST "RoarAudio"
39static char _libroar_null_buffer[] = NULL_BUFFER_CONST; // A byte sequense >= 8 byte.
40
41static inline void _libroar_null_buffer_check(void) {
42 if ( memcmp(_libroar_null_buffer, NULL_BUFFER_CONST, sizeof(_libroar_null_buffer)) != 0 )
43  roar_panic(ROAR_FATAL_ERROR_MEMORY_CORRUPTION_GUARD, NULL);
44 memcpy(_libroar_null_buffer, NULL_BUFFER_CONST, sizeof(_libroar_null_buffer));
45}
46
47#define _err(x) do { roar_err_set((x)); return NULL; } while (0)
48
49#ifdef ROAR_USE_MEMMGR
50void * roar_mm_calloc(size_t nmemb, size_t size) {
51 void * ret;
52
53 if ( nmemb == 0 || size == 0 ) {
54  _libroar_null_buffer_check();
55  return _libroar_null_buffer;
56 }
57
58#ifdef ROAR_HAVE_CALLOC
59 roar_err_clear_all();
60 ret = calloc(nmemb, size);
61
62 if ( ret == NULL )
63  roar_err_update();
64
65 return ret;
66#else
67 ret = roar_mm_malloc(nmemb*size);
68 if ( ret == NULL )
69  return NULL;
70
71 memset(ret, 0, nmemb*size);
72
73 return ret;
74#endif
75}
76
77void * roar_mm_malloc(size_t size) {
78 void * ret;
79
80 if ( size == 0 ) {
81  _libroar_null_buffer_check();
82  return _libroar_null_buffer;
83 }
84
85#ifdef ROAR_HAVE_MALLOC
86 roar_err_clear_all();
87 ret = malloc(size);
88
89 if ( ret == NULL )
90  roar_err_update();
91
92 return ret;
93#elif defined(ROAR_HAVE_CALLOC)
94 return roar_mm_calloc(1, size);
95#elif defined(ROAR_HAVE_REALLOC)
96 return roar_mm_realloc(NULL, size);
97#else
98 _err(ROAR_ERROR_NOSYS);
99#endif
100}
101
102int    roar_mm_free(void *ptr) {
103
104 if ( ptr == _libroar_null_buffer ) {
105  _libroar_null_buffer_check();
106  return 0;
107 }
108
109#ifdef ROAR_HAVE_FREE
110 free(ptr);
111 return 0;
112#elif defined(ROAR_HAVE_REALLOC)
113 if ( roar_mm_realloc(ptr, 0) != _libroar_null_buffer )
114  return -1;
115 return 0;
116#else
117 roar_err_set(ROAR_ERROR_NOSYS);
118 return -1;
119#endif
120}
121
122void * roar_mm_realloc(void *ptr, size_t size) {
123#ifdef ROAR_HAVE_REALLOC
124 void * ret;
125#endif
126
127 if ( ptr == NULL )
128  return roar_mm_malloc(size);
129
130 if ( size == 0 ) {
131  roar_mm_free(ptr);
132  _libroar_null_buffer_check();
133  return _libroar_null_buffer;
134 }
135
136#ifdef ROAR_HAVE_REALLOC
137 roar_err_clear_all();
138 ret = realloc(ptr, size);
139
140 if ( ret == NULL )
141  roar_err_update();
142
143 return ret;
144#else
145 _err(ROAR_ERROR_NOTSUP);
146#endif
147}
148#endif
149
150void * roar_mm_memdup(const void * s, size_t len) {
151 void * ret;
152
153 if ( s == NULL )
154  _err(ROAR_ERROR_FAULT);
155
156 if ( len == 0 ) {
157  _libroar_null_buffer_check();
158  return _libroar_null_buffer;
159 }
160
161 ret = roar_mm_malloc(len);
162
163 if ( ret == NULL )
164  return NULL;
165
166 memcpy(ret, s, len);
167
168 return ret;
169}
170
171#if defined(ROAR_USE_MEMMGR) || !defined(ROAR_HAVE_STRDUP)
172char * roar_mm_strdup(const char *s) {
173 void * ret;
174#ifndef ROAR_HAVE_STRDUP
175 ssize_t len;
176#endif
177
178 if ( s == NULL )
179  _err(ROAR_ERROR_FAULT);
180
181#ifdef ROAR_HAVE_STRDUP
182 roar_err_clear_all();
183 ret = strdup(s);
184
185 if ( ret == NULL )
186  roar_err_update();
187#else
188 len = roar_mm_strlen(s);
189 if ( len == -1 )
190  return NULL;
191
192 ret = roar_mm_memdup(s, len+1);
193#endif
194
195 return ret;
196}
197#endif
198
199#if defined(ROAR_USE_MEMMGR) || !defined(ROAR_HAVE_STRNDUP)
200char *roar_mm_strndup(const char *s, size_t n) {
201 void * ret;
202#ifndef ROAR_HAVE_STRDUP
203 ssize_t len;
204#endif
205
206 if ( s == NULL )
207  _err(ROAR_ERROR_FAULT);
208
209 if ( n == 0 ) {
210  _libroar_null_buffer_check();
211  return _libroar_null_buffer;
212 }
213
214#ifdef ROAR_HAVE_STRDUP
215 roar_err_clear_all();
216 ret = strndup(s, n);
217
218 if ( ret == NULL )
219  roar_err_update();
220#else
221 len = roar_mm_strnlen(s, n);
222 if ( len == -1 )
223  return NULL;
224
225 ret = roar_mm_memdup(s, len+1);
226#endif
227
228 return ret;
229}
230#endif
231
232#ifndef ROAR_HAVE_STRLEN
233ssize_t roar_mm_strlen(const char *s) {
234 size_t ret = 0;
235
236 if ( s == NULL ) {
237  roar_err_set(ROAR_ERROR_FAULT);
238  return -1;
239 }
240
241 for (; *s != 0; s++, ret++);
242
243 return ret;
244}
245#endif
246
247ssize_t roar_mm_strnlen(const char *s, size_t maxlen) {
248 size_t ret = 0;
249
250 if ( s == NULL ) {
251  roar_err_set(ROAR_ERROR_FAULT);
252  return -1;
253 }
254
255#ifdef ROAR_HAVE_STRNLEN
256 ret = strnlen(s, maxlen);
257#else
258 for (; ret < maxlen && *s != 0; s++, ret++);
259#endif
260
261 if ( ret == maxlen ) {
262  roar_err_set(ROAR_ERROR_MSGSIZE);
263  return -1;
264 }
265
266 return ret;
267}
268
269//ll
Note: See TracBrowser for help on using the repository browser.