/* * $Id: zmalloc.c,v 1.14 1998/07/08 13:41:37 ceder Exp $ * Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995 Lysator Academic Computer Association. * * This file is part of the LysKOM server. * * LysKOM 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 1, or (at your option) * any later version. * * LysKOM 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 LysKOM; see the file COPYING. If not, write to * Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN, * or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, * MA 02139, USA. * * Please mail bug reports to bug-lyskom@lysator.liu.se. */ /* * zmalloc.c * * * * Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995 Lysator Computer Club, * Linkoping University, Sweden * * Everyone is granted permission to copy, modify and redistribute * this code, provided the people they give it to can. * * * Author: Thomas Bellman * Lysator Computer Club * Linkoping University * Sweden * * email: Bellman@Lysator.LiU.SE * * * Any opinions expressed in this code are the author's PERSONAL opinions, * and does NOT, repeat NOT, represent any official standpoint of Lysator, * even if so stated. */ static const char * rcsid = "$Id: zmalloc.c,v 1.14 1998/07/08 13:41:37 ceder Exp $"; #include #ifdef HAVE_STDDEF_H # include #endif #ifdef HAVE_STDLIB_H # include #endif #if STDC_HEADERS || HAVE_STRING_H # include # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif #else /* not STDC_HEADERS and not HAVE_STRING_H */ # include /* memory.h and strings.h conflict on some systems. */ #endif /* not STDC_HEADERS and not HAVE_STRING_H */ #ifndef NULL # include #endif #include "compiler.h" #include "zmalloc.h" #include "rcs.h" USE(rcsid); #define EXPORT typedef struct { int refcount; size_t size; } z_info; #define REFCOUNT(pointer) \ (((z_info *) ((char *) pointer - sizeof (z_info)))->refcount) #define AREA_SIZE(pointer) \ (((z_info *) ((char *) pointer - sizeof (z_info)))->size) #define MIN(n1, n2) (((n1) < (n2)) ? (n1) : (n2)) EXPORT void * zmalloc (size_t size) { void * memory; memory = malloc (size + sizeof (z_info)); if (memory == NULL) return NULL; ((z_info *) memory)->size = size; ((z_info *) memory)->refcount = 1; return (char *) memory + sizeof (z_info); } EXPORT void * zcalloc (size_t n, size_t size) { void * memory; memory = malloc (n * size + sizeof (z_info)); if (memory == NULL) return NULL; ((z_info *) memory)->size = n * size; ((z_info *) memory)->refcount = 1; memset ((char *) memory + sizeof (z_info), 0, n * size); return (char *) memory + sizeof (z_info); } EXPORT void * zrealloc (void * ptr, size_t size) { void * memory; if (ptr == NULL) return zmalloc (size); if (REFCOUNT (ptr) > 1) { memory = zmalloc (size); if (memory == NULL) return NULL; memcpy (memory, ptr, MIN (size, AREA_SIZE (ptr))); --REFCOUNT (ptr); return memory; } else { memory = realloc ((char *) ptr - sizeof (z_info), size + sizeof (z_info)); return (char *) memory + sizeof (z_info); } } EXPORT void zfree (void * ptr) { if (ptr != NULL && --REFCOUNT (ptr) <= 0) { free ((char *) ptr - sizeof (z_info)); } } EXPORT void zdestruct (void * ptr) { if (ptr != NULL) free ((char *) ptr - sizeof (z_info)); } EXPORT void * zuse (void * ptr) { if (ptr != NULL) { ++REFCOUNT (ptr); } return ptr; } EXPORT void * zown (void * ptr) { void * memory; if (ptr == NULL) return NULL; if (REFCOUNT (ptr) == 1) return ptr; else { if ((memory = malloc (AREA_SIZE (ptr))) == NULL) return NULL; memcpy (memory, ptr, AREA_SIZE (ptr)); zfree (ptr); return memory; } }