/* * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil). * You may copy, distribute, and use this software as long as this * copyright statement is not removed. */ #include #include "malloc.h" /* * Function: realloc() * * Purpose: to re-allocate a data area. * * Arguments: cptr - pointer to area to reallocate * size - size to change area to * * Returns: pointer to new area (may be same area) * * Narrative: verify pointer is within malloc region * obtain mlist pointer from cptr * verify magic number is correct * verify inuse flag is set * verify connection to adjoining segments is correct * save requested size * round-up size to appropriate boundry * IF size is bigger than what is in this segment * try to join next segment to this segment * IF size is less than what is is this segment * determine leftover amount of space * ELSE * allocate new segment of size bites * IF allocation failed * return NULL * copy previous data to new segment * free previous segment * return new pointer * split of extra space in this segment (if any) * clear bytes beyound what they had before * return pointer to data */ #ifndef lint static char rcs_hdr[] = "$Id: realloc.c,v 1.1 1992/01/24 03:29:11 dvadura Exp $"; #endif char * realloc(cptr,size) char * cptr; unsigned int size; { void free(); char * func = "realloc"; int i; char * malloc(); extern int malloc_checking; extern struct mlist * malloc_end; extern int malloc_errno; extern char * malloc_data_end; extern char * malloc_data_start; void malloc_join(); void malloc_memset(); void malloc_split(); char * memcpy(); char * new_cptr; struct mlist * ptr; int r_size; /* * IF malloc chain checking is on, go do it. */ if( malloc_checking ) { (void) malloc_chain_check(1); } /* * verify that cptr is within the malloc region... */ if( cptr < malloc_data_start || cptr > malloc_data_end ) { malloc_errno = M_CODE_BAD_PTR; malloc_warning(func); return (NULL); } /* * convert pointer to mlist struct pointer. To do this we must * move the pointer backwards the correct number of bytes... */ ptr = (struct mlist *) (cptr - M_SIZE); if( (ptr->flag&M_MAGIC) != M_MAGIC ) { malloc_errno = M_CODE_BAD_MAGIC; malloc_warning(func); return(NULL); } if( ! (ptr->flag & M_INUSE) ) { malloc_errno = M_CODE_NOT_INUSE ; malloc_warning(func); return(NULL); } if( (ptr->prev && (ptr->prev->next != ptr) ) || (ptr->next && (ptr->next->prev != ptr) ) || ((ptr->next == NULL) && (ptr->prev == NULL)) ) { malloc_errno = M_CODE_BAD_CONNECT; malloc_warning(func); return(NULL); } r_size = ++size; M_ROUNDUP(size); if( size > ptr->s.size ) { malloc_join(ptr,ptr->next,1,1); } if( size > ptr->s.size ) { /* * else we can't combine it, so lets allocate a new chunk, * copy the data and free the old chunk... */ new_cptr = malloc(size); if( new_cptr == (char *) 0) { return(new_cptr); } if( r_size < ptr->r_size ) { i = r_size; } else { i = ptr->r_size; } (void)memcpy(new_cptr,ptr->data,i); free(cptr); return(new_cptr); } /* else... */ /* * save amount of real data in new segment (this will be used in the * memset later) and then save requested size of this segment. */ if( ptr->r_size < r_size ) { i = ptr->r_size; } else { i = r_size; } ptr->r_size = r_size; /* * split off extra free space at end of this segment, if possible... */ malloc_split(ptr); malloc_memset( ptr->data+i, M_FILL, (int) (ptr->s.size - i)); return(ptr->data); } /* realloc(... */ /* * $Log: realloc.c,v $ * Revision 1.1 1992/01/24 03:29:11 dvadura * dmake Version 3.8, Initial revision * * Revision 1.8 90/08/29 21:22:52 cpcahil * miscellaneous lint fixes * * Revision 1.7 90/05/11 00:13:10 cpcahil * added copyright statment * * Revision 1.6 90/02/25 11:01:20 cpcahil * added support for malloc chain checking. * * Revision 1.5 90/02/24 21:50:31 cpcahil * lots of lint fixes * * Revision 1.4 90/02/24 17:29:39 cpcahil * changed $Header to $Id so full path wouldnt be included as part of rcs * id string * * Revision 1.3 90/02/24 17:20:00 cpcahil * attempt to get rid of full path in rcs header. * * Revision 1.2 90/02/24 15:14:20 cpcahil * 1. added function header * 2. changed calls to malloc_warning to conform to new usage * 3. added setting of malloc_errno * 4. broke up bad pointer determination so that errno's would be more * descriptive * * Revision 1.1 90/02/22 23:17:43 cpcahil * Initial revision * */