153a5a1b3Sopenharmony_ci/*** 253a5a1b3Sopenharmony_ci This file is part of PulseAudio. 353a5a1b3Sopenharmony_ci 453a5a1b3Sopenharmony_ci Copyright 2004-2006 Lennart Poettering 553a5a1b3Sopenharmony_ci 653a5a1b3Sopenharmony_ci PulseAudio is free software; you can redistribute it and/or modify 753a5a1b3Sopenharmony_ci it under the terms of the GNU Lesser General Public License as published 853a5a1b3Sopenharmony_ci by the Free Software Foundation; either version 2.1 of the License, 953a5a1b3Sopenharmony_ci or (at your option) any later version. 1053a5a1b3Sopenharmony_ci 1153a5a1b3Sopenharmony_ci PulseAudio is distributed in the hope that it will be useful, but 1253a5a1b3Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 1353a5a1b3Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1453a5a1b3Sopenharmony_ci General Public License for more details. 1553a5a1b3Sopenharmony_ci 1653a5a1b3Sopenharmony_ci You should have received a copy of the GNU Lesser General Public License 1753a5a1b3Sopenharmony_ci along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. 1853a5a1b3Sopenharmony_ci***/ 1953a5a1b3Sopenharmony_ci 2053a5a1b3Sopenharmony_ci#ifdef HAVE_CONFIG_H 2153a5a1b3Sopenharmony_ci#include <config.h> 2253a5a1b3Sopenharmony_ci#endif 2353a5a1b3Sopenharmony_ci 2453a5a1b3Sopenharmony_ci#include <stdlib.h> 2553a5a1b3Sopenharmony_ci#include <signal.h> 2653a5a1b3Sopenharmony_ci#include <unistd.h> 2753a5a1b3Sopenharmony_ci#include <string.h> 2853a5a1b3Sopenharmony_ci#include <errno.h> 2953a5a1b3Sopenharmony_ci 3053a5a1b3Sopenharmony_ci#include <pulse/gccmacro.h> 3153a5a1b3Sopenharmony_ci#include <pulsecore/core-util.h> 3253a5a1b3Sopenharmony_ci#include <pulsecore/macro.h> 3353a5a1b3Sopenharmony_ci 3453a5a1b3Sopenharmony_ci#include "xmalloc.h" 3553a5a1b3Sopenharmony_ci 3653a5a1b3Sopenharmony_ci/* Make sure not to allocate more than this much memory. */ 3753a5a1b3Sopenharmony_ci#define MAX_ALLOC_SIZE (1024*1024*96) /* 96MB */ 3853a5a1b3Sopenharmony_ci 3953a5a1b3Sopenharmony_ci/* #undef malloc */ 4053a5a1b3Sopenharmony_ci/* #undef free */ 4153a5a1b3Sopenharmony_ci/* #undef realloc */ 4253a5a1b3Sopenharmony_ci/* #undef strndup */ 4353a5a1b3Sopenharmony_ci/* #undef strdup */ 4453a5a1b3Sopenharmony_ci 4553a5a1b3Sopenharmony_cistatic void oom(void) PA_GCC_NORETURN; 4653a5a1b3Sopenharmony_ci 4753a5a1b3Sopenharmony_ci/* called in case of an OOM situation. Prints an error message and 4853a5a1b3Sopenharmony_ci * exits */ 4953a5a1b3Sopenharmony_cistatic void oom(void) { 5053a5a1b3Sopenharmony_ci static const char e[] = "Not enough memory\n"; 5153a5a1b3Sopenharmony_ci pa_loop_write(STDERR_FILENO, e, sizeof(e)-1, NULL); 5253a5a1b3Sopenharmony_ci#ifdef SIGQUIT 5353a5a1b3Sopenharmony_ci raise(SIGQUIT); 5453a5a1b3Sopenharmony_ci#endif 5553a5a1b3Sopenharmony_ci _exit(1); 5653a5a1b3Sopenharmony_ci} 5753a5a1b3Sopenharmony_ci 5853a5a1b3Sopenharmony_civoid* pa_xmalloc(size_t size) { 5953a5a1b3Sopenharmony_ci void *p; 6053a5a1b3Sopenharmony_ci pa_assert(size > 0); 6153a5a1b3Sopenharmony_ci pa_assert(size < MAX_ALLOC_SIZE); 6253a5a1b3Sopenharmony_ci 6353a5a1b3Sopenharmony_ci if (!(p = malloc(size))) 6453a5a1b3Sopenharmony_ci oom(); 6553a5a1b3Sopenharmony_ci 6653a5a1b3Sopenharmony_ci return p; 6753a5a1b3Sopenharmony_ci} 6853a5a1b3Sopenharmony_ci 6953a5a1b3Sopenharmony_civoid* pa_xmalloc0(size_t size) { 7053a5a1b3Sopenharmony_ci void *p; 7153a5a1b3Sopenharmony_ci pa_assert(size > 0); 7253a5a1b3Sopenharmony_ci pa_assert(size < MAX_ALLOC_SIZE); 7353a5a1b3Sopenharmony_ci 7453a5a1b3Sopenharmony_ci if (!(p = calloc(1, size))) 7553a5a1b3Sopenharmony_ci oom(); 7653a5a1b3Sopenharmony_ci 7753a5a1b3Sopenharmony_ci return p; 7853a5a1b3Sopenharmony_ci} 7953a5a1b3Sopenharmony_ci 8053a5a1b3Sopenharmony_civoid *pa_xrealloc(void *ptr, size_t size) { 8153a5a1b3Sopenharmony_ci void *p; 8253a5a1b3Sopenharmony_ci pa_assert(size > 0); 8353a5a1b3Sopenharmony_ci pa_assert(size < MAX_ALLOC_SIZE); 8453a5a1b3Sopenharmony_ci 8553a5a1b3Sopenharmony_ci if (!(p = realloc(ptr, size))) 8653a5a1b3Sopenharmony_ci oom(); 8753a5a1b3Sopenharmony_ci return p; 8853a5a1b3Sopenharmony_ci} 8953a5a1b3Sopenharmony_ci 9053a5a1b3Sopenharmony_civoid* pa_xmemdup(const void *p, size_t l) { 9153a5a1b3Sopenharmony_ci if (!p) 9253a5a1b3Sopenharmony_ci return NULL; 9353a5a1b3Sopenharmony_ci else { 9453a5a1b3Sopenharmony_ci char *r = pa_xmalloc(l); 9553a5a1b3Sopenharmony_ci memcpy(r, p, l); 9653a5a1b3Sopenharmony_ci return r; 9753a5a1b3Sopenharmony_ci } 9853a5a1b3Sopenharmony_ci} 9953a5a1b3Sopenharmony_ci 10053a5a1b3Sopenharmony_cichar *pa_xstrdup(const char *s) { 10153a5a1b3Sopenharmony_ci if (!s) 10253a5a1b3Sopenharmony_ci return NULL; 10353a5a1b3Sopenharmony_ci 10453a5a1b3Sopenharmony_ci return pa_xmemdup(s, strlen(s)+1); 10553a5a1b3Sopenharmony_ci} 10653a5a1b3Sopenharmony_ci 10753a5a1b3Sopenharmony_cichar *pa_xstrndup(const char *s, size_t l) { 10853a5a1b3Sopenharmony_ci char *e, *r; 10953a5a1b3Sopenharmony_ci 11053a5a1b3Sopenharmony_ci if (!s) 11153a5a1b3Sopenharmony_ci return NULL; 11253a5a1b3Sopenharmony_ci 11353a5a1b3Sopenharmony_ci if ((e = memchr(s, 0, l))) 11453a5a1b3Sopenharmony_ci return pa_xmemdup(s, (size_t) (e-s+1)); 11553a5a1b3Sopenharmony_ci 11653a5a1b3Sopenharmony_ci r = pa_xmalloc(l+1); 11753a5a1b3Sopenharmony_ci memcpy(r, s, l); 11853a5a1b3Sopenharmony_ci r[l] = 0; 11953a5a1b3Sopenharmony_ci return r; 12053a5a1b3Sopenharmony_ci} 12153a5a1b3Sopenharmony_ci 12253a5a1b3Sopenharmony_civoid pa_xfree(void *p) { 12353a5a1b3Sopenharmony_ci int saved_errno; 12453a5a1b3Sopenharmony_ci 12553a5a1b3Sopenharmony_ci if (!p) 12653a5a1b3Sopenharmony_ci return; 12753a5a1b3Sopenharmony_ci 12853a5a1b3Sopenharmony_ci saved_errno = errno; 12953a5a1b3Sopenharmony_ci free(p); 13053a5a1b3Sopenharmony_ci errno = saved_errno; 13153a5a1b3Sopenharmony_ci} 132