/** BEGIN COPYRIGHT BLOCK * 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; 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. * * You should have received a copy of the GNU General Public License along with * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place, Suite 330, Boston, MA 02111-1307 USA. * * In addition, as a special exception, Red Hat, Inc. gives You the additional * right to link the code of this Program with code not covered under the GNU * General Public License ("Non-GPL Code") and to distribute linked combinations * including the two, subject to the limitations in this paragraph. Non-GPL Code * permitted under this exception must only link to the code of this Program * through those well defined interfaces identified in the file named EXCEPTION * found in the source code files (the "Approved Interfaces"). The files of * Non-GPL Code may instantiate templates or use macros or inline functions from * the Approved Interfaces without causing the resulting work to be covered by * the GNU General Public License. Only Red Hat, Inc. may make changes or * additions to the list of Approved Interfaces. You must obey the GNU General * Public License in all respects for all of the Program code and other code used * in conjunction with the Program except the Non-GPL Code covered by this * exception. If you modify this file, you may extend this exception to your * version of the file, but you are not obligated to do so. If you do not wish to * provide this exception without modification, you must delete this exception * statement from your version and license this file solely under the GPL without * exception. * * * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission. * Copyright (C) 2005 Red Hat, Inc. * All rights reserved. * END COPYRIGHT BLOCK **/ #ifdef HAVE_CONFIG_H # include #endif /* * system.c: A grab bag of system-level abstractions * * Many authors */ #include "netsite.h" #include "prlog.h" #include "base/ereport.h" #ifdef XP_WIN32 #include #endif #include "base/systems.h" /* find out if we have malloc pools */ static int thread_malloc_key = -1; #if defined(MALLOC_POOLS) && defined(THREAD_ANY) #include "base/pool.h" #include "base/systhr.h" #define MALLOC_KEY \ ((pool_handle_t *)(thread_malloc_key != -1 ? systhread_getdata(thread_malloc_key) : NULL)) #endif #ifdef MCC_DEBUG #define DEBUG_MALLOC #endif #ifdef DEBUG_MALLOC /* The debug malloc routines provide several functions: * * - detect allocated memory overflow/underflow * - detect multiple frees * - intentionally clobbers malloc'd buffers * - intentionally clobbers freed buffers */ #define DEBUG_MAGIC 0x12345678 #define DEBUG_MARGIN 32 #define DEBUG_MARGIN_CHAR '*' #define DEBUG_MALLOC_CHAR '.' #define DEBUG_FREE_CHAR 'X' #endif /* DEBUG_MALLOC */ NSAPI_PUBLIC void *system_malloc(int size) { #if defined(MALLOC_POOLS) && defined(THREAD_ANY) return pool_malloc(MALLOC_KEY, size); #else return malloc(size); #endif } NSAPI_PUBLIC void *system_calloc(int size) { void *ret; #if defined(MALLOC_POOLS) && defined(THREAD_ANY) ret = pool_malloc(MALLOC_KEY, size); #else ret = malloc(size); #endif if(ret) ZERO(ret, size); return ret; } NSAPI_PUBLIC void *system_realloc(void *ptr, int size) { #if defined(MALLOC_POOLS) && defined(THREAD_ANY) return pool_realloc(MALLOC_KEY, ptr, size); #else return realloc(ptr, size); #endif } NSAPI_PUBLIC void system_free(void *ptr) { #if defined(MALLOC_POOLS) && defined(THREAD_ANY) pool_free(MALLOC_KEY, ptr); #else PR_ASSERT(ptr); free(ptr); #endif } NSAPI_PUBLIC char *system_strdup(const char *ptr) { PR_ASSERT(ptr); #if defined(MALLOC_POOLS) && defined(THREAD_ANY) return pool_strdup(MALLOC_KEY, ptr); #else return strdup(ptr); #endif } NSAPI_PUBLIC void *system_malloc_perm(int size) { #ifndef DEBUG_MALLOC return malloc(size); #else char *ptr = (char *)malloc(size + 2*DEBUG_MARGIN+2*sizeof(int)); char *real_ptr; int *magic; int *length; magic = (int *)ptr; *magic = DEBUG_MAGIC; ptr += sizeof(int); length = (int *)ptr; *length = size; ptr += sizeof(int); memset(ptr, DEBUG_MARGIN_CHAR, DEBUG_MARGIN); ptr += DEBUG_MARGIN; memset(ptr, DEBUG_MALLOC_CHAR, size); real_ptr = ptr; ptr += size; memset(ptr, DEBUG_MARGIN_CHAR, DEBUG_MARGIN); return real_ptr; #endif } NSAPI_PUBLIC void *system_calloc_perm(int size) { void *ret = system_malloc_perm(size); if(ret) ZERO(ret, size); return ret; } NSAPI_PUBLIC void *system_realloc_perm(void *ptr, int size) { #ifndef DEBUG_MALLOC return realloc(ptr, size); #else int *magic, *length; char *cptr; cptr = (char *)ptr - DEBUG_MARGIN - 2 * sizeof(int); magic = (int *)cptr; if (*magic == DEBUG_MAGIC) { cptr += sizeof(int); length = (int *)cptr; if (*length < size) { char *newptr = (char *)system_malloc_perm(size); memcpy(newptr, ptr, *length); system_free_perm(ptr); return newptr; }else { return ptr; } } else { ereport(LOG_WARN, "realloc: attempt to realloc to smaller size"); return realloc(ptr, size); } #endif } NSAPI_PUBLIC void system_free_perm(void *ptr) { #ifdef DEBUG_MALLOC int *length, *magic; char *baseptr, *cptr; int index; PR_ASSERT(ptr); cptr = baseptr = ((char *)ptr) - DEBUG_MARGIN - 2*sizeof(int); magic = (int *)cptr; if (*magic == DEBUG_MAGIC) { cptr += sizeof(int); length = (int *)cptr; cptr += sizeof(int); for (index=0; index