dmake/dmake/dbug/malloc/free.c

189 lines
4.5 KiB
C

/*
* (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 <stdio.h>
#include "malloc.h"
#include "debug.h"
/*
* Function: free()
*
* Purpose: to deallocate malloced data
*
* Arguments: ptr - pointer to data area to deallocate
*
* Returns: nothing of any value
*
* Narrative:
* verify pointer is within malloc region
* get mlist pointer from passed address
* verify magic number
* verify inuse flag
* verify pointer connections with surrounding segments
* turn off inuse flag
* verify no data overrun into non-malloced area at end of segment
* IF possible join segment with next segment
* IF possible join segment with previous segment
* Clear all data in segment (to make sure it isn't reused)
*
*/
#ifndef lint
static
char rcs_hdr[] = "$Id: free.c,v 1.1 1992/01/24 03:29:02 dvadura Exp $";
#endif
void
free(cptr)
char * cptr;
{
char * func = "free";
int i;
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();
struct mlist * oldptr;
struct mlist * ptr;
/*
* 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;
}
/*
* 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;
}
if( ! (ptr->flag & M_INUSE) )
{
malloc_errno = M_CODE_NOT_INUSE;
malloc_warning(func);
return;
}
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;
}
ptr->flag &= ~M_INUSE;
/*
* verify that the user did not overrun the requested number of bytes.
*/
for(i=ptr->r_size; i < ptr->s.size; i++)
{
if( ptr->data[i] != M_FILL )
{
malloc_errno = M_CODE_OVERRUN;
malloc_warning(func);
break;
}
}
DEBUG3(10,"pointers: prev: 0x%.7x, ptr: 0x%.7x, next: 0x%.7x",
ptr->prev, ptr, ptr->next);
DEBUG3(10,"size: prev: %9d, ptr: %9d, next: %9d",
ptr->prev->s.size, ptr->s.size, ptr->next->s.size);
DEBUG3(10,"flags: prev: 0x%.7x, ptr: 0x%.7x, next: 0x%.7x",
ptr->prev->flag, ptr->flag, ptr->next->flag);
/*
* check to see if this block can be combined with the next and/or
* previous block. Since it may be joined with the previous block
* we will save a pointer to the previous block and test to verify
* if it is joined (it's next ptr will no longer point to ptr).
*/
malloc_join(ptr,ptr->next,0,0);
oldptr = ptr->prev;
malloc_join(ptr->prev, ptr,0,0);
if( oldptr->next != ptr )
{
DEBUG0(10,"Oldptr was changed");
ptr = oldptr;
}
/*
* fill this block with '\02's to ensure that nobody is using a
* pointer to already freed data...
*/
malloc_memset(ptr->data,M_FREE_FILL,(int)ptr->s.size);
}
/*
* $Log: free.c,v $
* Revision 1.1 1992/01/24 03:29:02 dvadura
* dmake Version 3.8, Initial revision
*
* Revision 1.9 90/08/29 21:22:48 cpcahil
* miscellaneous lint fixes
*
* Revision 1.8 90/05/11 00:13:08 cpcahil
* added copyright statment
*
* Revision 1.7 90/02/25 11:00:18 cpcahil
* added support for malloc chain checking.
*
* Revision 1.6 90/02/24 21:50:18 cpcahil
* lots of lint fixes
*
* Revision 1.5 90/02/24 17:29:13 cpcahil
* changed $Header to $Id so full path wouldnt be included as part of rcs
* id string
*
* Revision 1.4 90/02/24 15:15:32 cpcahil
* 1. changed ALREADY_FREE errno to NOT_INUSE so that the same errno could
* be used by both free and realloc (since it was the same error).
* 2. fixed coding bug
*
* Revision 1.3 90/02/24 14:23:45 cpcahil
* fixed malloc_warning calls
*
* Revision 1.2 90/02/24 13:59:10 cpcahil
* added function header.
* Modified calls to malloc_warning/malloc_fatal to use new code error messages
* Added support for malloc_errno setting of error codes.
*
* Revision 1.1 90/02/22 23:17:43 cpcahil
* Initial revision
*
*/