X-Git-Url: http://git.silcnet.org/gitweb/?p=crypto.git;a=blobdiff_plain;f=lib%2Fsilcutil%2Fsilcmemory.c;h=b1a657b2f335593c91bba82875d9e2ea1d8fb8f6;hp=e5ebae567a4d0767611fb80239735f5545a02472;hb=9332a955b1c06b31268b6359b3c78f8e85daee04;hpb=318d79b391bf6288e3e28c840217a7097f3d0392 diff --git a/lib/silcutil/silcmemory.c b/lib/silcutil/silcmemory.c index e5ebae56..b1a657b2 100644 --- a/lib/silcutil/silcmemory.c +++ b/lib/silcutil/silcmemory.c @@ -2,83 +2,85 @@ silcmemory.c - Author: Pekka Riikonen + Author: Pekka Riikonen - Copyright (C) 1999 - 2000 Pekka Riikonen + Copyright (C) 1999 - 2008 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - + the Free Software Foundation; version 2 of the License. + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. */ -/* - * $Id$ - * $Log$ - * Revision 1.1 2000/09/13 17:45:16 priikone - * Splitted SILC core library. Core library includes now only - * SILC protocol specific stuff. New utility library includes the - * old stuff from core library that is more generic purpose stuff. - * - * Revision 1.2 2000/07/05 06:05:56 priikone - * Assert if system is out of memory. - * - * Revision 1.1.1.1 2000/06/27 11:36:55 priikone - * Imported from internal CVS/Added Log headers. - * - * - */ - -#include "silcincludes.h" +/* $Id$ */ + +#include "silc.h" + +#ifndef SILC_STACKTRACE + +#define SILC_MAX_ALLOC (1024 * 1024L * 1024L) void *silc_malloc(size_t size) { void *addr; -#ifdef HAVE_MLOCK - addr = malloc(size); - assert(addr != NULL); - mlock(addr, size); - return addr; -#else + + if (silc_unlikely(size <= 0 || size >= SILC_MAX_ALLOC)) { + if (size == 0) + silc_set_errno_nofail(SILC_ERR_ZERO_ALLOCATION); + else + silc_set_errno_reason_nofail(SILC_ERR_TOO_LARGE_ALLOCATION, + "Allocation by %d", size); + return NULL; + } + addr = malloc(size); - assert(addr != NULL); + if (silc_unlikely(!addr)) + silc_set_errno_nofail(SILC_ERR_OUT_OF_MEMORY); + return addr; -#endif } void *silc_calloc(size_t items, size_t size) { void *addr; -#ifdef HAVE_MLOCK - addr = calloc(items, size); - assert(addr != NULL); - mlock(addr, size); - return addr; -#else + + if (silc_unlikely(size * items <= 0 || size * items >= SILC_MAX_ALLOC)) { + if (size == 0) + silc_set_errno_nofail(SILC_ERR_ZERO_ALLOCATION); + else + silc_set_errno_reason_nofail(SILC_ERR_TOO_LARGE_ALLOCATION, + "Allocation by %d", size); + return NULL; + } + addr = calloc(items, size); - assert(addr != NULL); + if (silc_unlikely(!addr)) + silc_set_errno_nofail(SILC_ERR_OUT_OF_MEMORY); + return addr; -#endif } void *silc_realloc(void *ptr, size_t size) { void *addr; -#ifdef HAVE_MLOCK - addr = realloc(ptr, size); - assert(addr != NULL); - mlock(addr, size); - return addr; -#else + if (silc_unlikely(size <= 0 || size >= SILC_MAX_ALLOC)) { + if (size == 0) + silc_set_errno_nofail(SILC_ERR_ZERO_ALLOCATION); + else + silc_set_errno_reason_nofail(SILC_ERR_TOO_LARGE_ALLOCATION, + "Allocation by %d", size); + return NULL; + } + addr = realloc(ptr, size); - assert(addr != NULL); + if (silc_unlikely(!addr)) + silc_set_errno_nofail(SILC_ERR_OUT_OF_MEMORY); + return addr; -#endif } void silc_free(void *ptr) @@ -86,9 +88,106 @@ void silc_free(void *ptr) free(ptr); } +void *silc_memdup(const void *ptr, size_t size) +{ + unsigned char *addr; + + addr = silc_malloc(size + 1); + if (silc_unlikely(!addr)) { + silc_set_errno_nofail(SILC_ERR_OUT_OF_MEMORY); + return NULL; + } + memcpy((void *)addr, ptr, size); + addr[size] = '\0'; + return (void *)addr; +} + +char *silc_strdup(const char *str) +{ + return silc_memdup(str, strlen(str)); +} + +#endif /* !SILC_STACKTRACE */ + +/* SilcStack aware routines */ + +void *silc_smalloc(SilcStack stack, SilcUInt32 size) +{ + return stack ? silc_stack_malloc(stack, size) : silc_malloc(size); +} + +void silc_sfree(SilcStack stack, void *ptr) +{ + if (stack) { +#ifdef SILC_DEBUG + if (ptr) + *(unsigned char *)ptr = 'F'; +#endif /* SILC_DEBUG */ + return; + } + silc_free(ptr); +} + +void *silc_scalloc(SilcStack stack, SilcUInt32 items, SilcUInt32 size) +{ + unsigned char *addr; + + if (!stack) + return silc_calloc(items, size); + + addr = silc_stack_malloc(stack, items * size); + if (silc_unlikely(!addr)) + return NULL; + memset(addr, 0, items * size); + return (void *)addr; +} + +void *silc_srealloc(SilcStack stack, SilcUInt32 old_size, + void *ptr, SilcUInt32 size) +{ + void *new_ptr; + + if (!stack) + return silc_realloc(ptr, size); + + new_ptr = silc_stack_realloc(stack, old_size, ptr, size); + if (!new_ptr) { + new_ptr = silc_smalloc(stack, size); + if (!new_ptr) + return NULL; + memcpy(new_ptr, ptr, old_size); + } + + return new_ptr; +} +void *silc_smemdup(SilcStack stack, const void *ptr, SilcUInt32 size) +{ + unsigned char *addr; + if (!stack) + return silc_memdup(ptr, size); + addr = silc_stack_malloc(stack, size + 1); + if (silc_unlikely(!addr)) + return NULL; + memcpy((void *)addr, ptr, size); + addr[size] = '\0'; + return (void *)addr; +} +char *silc_sstrdup(SilcStack stack, const char *str) +{ + SilcInt32 size = strlen(str); + char *addr; + if (!stack) + return silc_memdup(str, size); + addr = silc_stack_malloc(stack, size + 1); + if (silc_unlikely(!addr)) + return NULL; + memcpy((void *)addr, str, size); + addr[size] = '\0'; + return addr; +}