v22i113: Debugging malloc() library, Part02/02

Rich Salz rsalz at bbn.com
Sat Jul 14 03:50:29 AEST 1990


Submitted-by: "Conor P. Cahill" <virtech!cpcahil at uunet.uu.net>
Posting-number: Volume 22, Issue 113
Archive-name: debug_malloc/part02

#!/bin/sh
# This is part 02 of Malloclib
if touch 2>&1 | fgrep '[-amc]' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= malloc.h ==============
if test X"$1" != X"-c" -a -f 'malloc.h'; then
	echo "File already exists: skipping 'malloc.h'"
else
echo "x - extracting malloc.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > malloc.h &&
X/*
X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
X * You may copy, distribute, and use this software as long as this
X * copyright statement is not removed.
X */
X/*
X * $Id: malloc.h,v 1.3 90/05/11 11:04:10 cpcahil Exp $
X */
Xstruct mlist
X{
X	struct mlist	* next;			/* next entry in chain	*/
X	struct mlist	* prev;			/* prev entry in chain	*/
X	int	 	  flag;			/* inuse flag		*/
X	unsigned int	  r_size;		/* requested size	*/
X	union
X	{
X		unsigned int	  size;		/* actual size		*/
X		double		  unused_just_for_alignment;
X	} s;
X	char		  data[4];
X};
X
X#define M_SIZE		((int)(char *)((struct mlist *)0)->data)
X#define M_RND		0x08
X
X#define M_INUSE 	0x01
X#define M_MAGIC 	0x03156100
X
X#define M_BLOCKSIZE	(1024*8)
X
X#define M_FILL		'\01'
X#define M_FREE_FILL	'\02'
X
X#define M_ROUNDUP(size)	{\
X				if( size & (M_RND-1) ) \
X				{ \
X					size &= ~(M_RND-1); \
X					size += M_RND; \
X				} \
X			}
X
X/*
X * Malloc warning/fatal error handler defines...
X */
X#define M_HANDLE_DUMP	0x80  /* 128 */
X#define M_HANDLE_IGNORE	0
X#define M_HANDLE_ABORT	1
X#define M_HANDLE_EXIT	2
X#define M_HANDLE_CORE	3
X	
X/*
X * Mallopt commands and defaults
X */
X
X#define MALLOC_WARN	1		/* set malloc warning handling	*/
X#define MALLOC_FATAL	2		/* set malloc fatal handling	*/
X#define MALLOC_ERRFILE	3		/* specify malloc error file	*/
X#define MALLOC_CKCHAIN	4		/* turn on chain checking	*/
X
X
X/*
X * Malloc warning/fatal error codes
X */
X
X#define M_CODE_CHAIN_BROKE	1	/* malloc chain is broken	*/
X#define M_CODE_NO_END		2	/* chain end != endptr		*/
X#define M_CODE_BAD_PTR		3	/* pointer not in malloc area	*/
X#define M_CODE_BAD_MAGIC	4	/* bad magic number in header	*/
X#define M_CODE_BAD_CONNECT	5	/* chain poingers corrupt	*/
X#define M_CODE_OVERRUN		6	/* data overrun in malloc seg	*/
X#define M_CODE_REUSE		7	/* reuse of freed area		*/
X#define M_CODE_NOT_INUSE	8	/* pointer is not in use	*/
X#define M_CODE_NOMORE_MEM	9	/* no more memory available	*/
X#define M_CODE_OUTOF_BOUNDS	10	/* gone beyound bounds 		*/
X
Xvoid malloc_warning();
Xvoid malloc_fatal();
Xvoid malloc_check_data();
Xvoid malloc_check_str();
Xvoid malloc_verify();
X
X/*
X * $Log:	malloc.h,v $
X * Revision 1.3  90/05/11  11:04:10  cpcahil
X * took out some extraneous lines
X * 
X * Revision 1.2  90/05/11  00:13:09  cpcahil
X * added copyright statment
X * 
X * Revision 1.1  90/02/23  07:09:03  cpcahil
X * Initial revision
X * 
X */
SHAR_EOF
$TOUCH -am 0511110490 malloc.h &&
chmod 0444 malloc.h ||
echo "restore of malloc.h failed"
set `wc -c malloc.h`;Wc_c=$1
if test "$Wc_c" != "2346"; then
	echo original size 2346, current size $Wc_c
fi
fi
# ============= malloc_chk.c ==============
if test X"$1" != X"-c" -a -f 'malloc_chk.c'; then
	echo "File already exists: skipping 'malloc_chk.c'"
else
echo "x - extracting malloc_chk.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > malloc_chk.c &&
X/*
X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
X * You may copy, distribute, and use this software as long as this
X * copyright statement is not removed.
X */
X
X#include <stdio.h>
X#include "malloc.h"
X#include "debug.h"
X
X#ifndef lint
Xstatic
Xchar rcs_hdr[] = "$Id: malloc_chk.c,v 1.4 90/05/11 00:13:09 cpcahil Exp $";
X#endif
X
Xextern struct mlist	  malloc_start;
Xextern struct mlist	* malloc_end;
Xextern char		* malloc_data_start;
Xextern char		* malloc_data_end;
X
X/*
X * Function:	malloc_in_arena()
X *
X * Purpose:	to verify address is within malloc arena.
X *
X * Arguments:	ptr	- pointer to verify
X *
X * Returns:	TRUE	- if pointer is within malloc area
X *		FALSE	- otherwise
X *
X * Narrative:
X *   IF pointer is >= malloc area start AND <= malloc area end
X *      return TRUE
X *   ELSE
X *      return FALSE
X *
X * Mod History:	
X *   90/01/24	cpcahil		Initial revision.
X */
Xint
Xmalloc_in_arena(ptr)
X	char	* ptr;
X{
X	extern char	* malloc_data_start;
X	extern char	* malloc_data_end;
X	int		  rtn = 0;
X
X	if( ptr >= malloc_data_start && ptr <= malloc_data_end )
X	{
X		rtn = 1;
X	}
X	
X	return(rtn);
X}
X
X/*
X * Function:	malloc_check_str()
X *
X * Arguments:	func	- name of function calling this routine
X *		str	- pointer to area to check
X *
X * Purpose:	to verify that if str is within the malloc arena, the data 
X *		it points to does not extend beyond the applicable region.
X *
X * Returns:	Nothing of any use (function is void).
X *
X * Narrative:
X *   IF pointer is within malloc arena
X *      determin length of string
X *      call malloc_verify() to verify data is withing applicable region
X *   return 
X *
X * Mod History:	
X *   90/01/24	cpcahil		Initial revision.
X *   90/01/29	cpcahil		Added code to ignore recursive calls.
X */
Xvoid
Xmalloc_check_str(func,str)
X	char		* func;
X	char		* str;
X{
X	static int	  layers;
X	register char	* s;
X
X	if( (layers++ == 0) &&  malloc_in_arena(str) )
X	{
X		for( s=str; *s; s++)
X		{
X		}
X		
X		malloc_verify(func,str,s-str+1);
X	}
X
X	layers--;
X}
X
X/*
X * Function:	malloc_check_data()
X *
X * Arguments:	func	- name of function calling this routine
X *		ptr	- pointer to area to check
X *		len 	- length to verify
X *
X * Purpose:	to verify that if ptr is within the malloc arena, the data 
X *		it points to does not extend beyond the applicable region.
X *
X * Returns:	Nothing of any use (function is void).
X *
X * Narrative:
X *   IF pointer is within malloc arena
X *      call malloc_verify() to verify data is withing applicable region
X *   return 
X *
X * Mod History:	
X *   90/01/24	cpcahil		Initial revision.
X *   90/01/29	cpcahil		Added code to ignore recursive calls.
X */
Xvoid
Xmalloc_check_data(func,ptr,len)
X	char		* func;
X	char		* ptr;
X	int		  len;
X{
X	static int	  layers;
X
X	if( layers++ == 0 )
X	{
X		DEBUG3(40,"malloc_check_data(%s,0x%x,%d) called...",
X			func,ptr,len);
X		if( malloc_in_arena(ptr) )
X		{
X			DEBUG0(10,"pointer in malloc arena, verifying...");
X			malloc_verify(func,ptr,len);
X		}
X	}
X
X	layers--;
X}
X
X/*
X * Function:	malloc_verify()
X *
X * Arguments:	func	- name of function calling the malloc check routines
X *		ptr	- pointer to area to check
X *		len 	- length to verify
X *
X * Purpose:	to verify that the data ptr points to does not extend beyond
X *		the applicable malloc region.  This function is only called 
X *		if it has been determined that ptr points into the malloc arena.
X *
X * Returns:	Nothing of any use (function is void).
X *
X * Narrative:
X *
X * Mod History:	
X *   90/01/24	cpcahil		Initial revision.
X */
Xvoid
Xmalloc_verify(func,ptr,len)
X	char		* func;
X	char		* ptr;
X	int		  len;
X{
X	extern struct mlist	* malloc_end;
X	extern int		  malloc_errno;
X	extern struct mlist 	  malloc_start;
X	struct mlist		* mptr;
X	
X	DEBUG3(40,"malloc_verify(%s,0x%x,%d) called...", func,ptr,len);
X	/*
X	 * Find the malloc block that includes this pointer
X	 */
X	mptr = &malloc_start;
X	while( mptr && 
X		! (((char *)mptr < ptr) && ((mptr->data+mptr->s.size) > ptr) ) )
X	{
X		mptr = mptr->next;
X	}
X
X	/*
X	 * if ptr was not in a malloc block, it must be part of
X	 *    some direct sbrk() stuff, so just return.
X	 */
X	if( ! mptr )
X	{
X		DEBUG1(10,"ptr (0x%x) not found in malloc search", ptr);
X		return;
X	}
X	
X	/*
X 	 * Now we have a valid malloc block that contains the indicated
X	 * pointer.  We must verify that it is withing the requested block
X	 * size (as opposed to the real block size which is rounded up to
X	 * allow for correct alignment).
X	 */
X
X	DEBUG4(60,"Checking  0x%x-0x%x, 0x%x-0x%x",
X			ptr, ptr+len, mptr->data, mptr->data+mptr->r_size);
X	
X	if( (ptr < mptr->data) || ((ptr+len) > (mptr->data+mptr->r_size)) )
X	{
X		DEBUG4(0,"pointer not within region 0x%x-0x%x, 0x%x-0x%x",
X			ptr, ptr+len, mptr->data, mptr->data+mptr->r_size);
X
X		malloc_errno = M_CODE_OUTOF_BOUNDS;
X		malloc_warning(func);
X	}
X
X	return;
X}
X
X/*
X * $Log:	malloc_chk.c,v $
X * Revision 1.4  90/05/11  00:13:09  cpcahil
X * added copyright statment
X * 
X * Revision 1.3  90/02/24  21:50:22  cpcahil
X * lots of lint fixes
X * 
X * Revision 1.2  90/02/24  17:29:38  cpcahil
X * changed $Header to $Id so full path wouldnt be included as part of rcs 
X * id string
X * 
X * Revision 1.1  90/02/24  14:57:03  cpcahil
X * Initial revision
X * 
X */
SHAR_EOF
$TOUCH -am 0511001490 malloc_chk.c &&
chmod 0444 malloc_chk.c ||
echo "restore of malloc_chk.c failed"
set `wc -c malloc_chk.c`;Wc_c=$1
if test "$Wc_c" != "5125"; then
	echo original size 5125, current size $Wc_c
fi
fi
# ============= malloc_chn.c ==============
if test X"$1" != X"-c" -a -f 'malloc_chn.c'; then
	echo "File already exists: skipping 'malloc_chn.c'"
else
echo "x - extracting malloc_chn.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > malloc_chn.c &&
X/*
X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
X * You may copy, distribute, and use this software as long as this
X * copyright statement is not removed.
X */
X#include <stdio.h>
X#include <fcntl.h>
X#include "malloc.h"
X
X/*
X * Function:	malloc_chain_check()
X *
X * Purpose:	to verify malloc chain is intact
X *
X * Arguments:	todo	- 0 - just check and return status
X *			  1 - call malloc_warn if error detected
X *
X * Returns:	0	- malloc chain intact & no overflows
X *		other	- problems detected in malloc chain
X *
X * Narrative:
X *
X * Notes:	If todo is non-zero the malloc_warn function, when called
X *		may not return (i.e. it may exit)
X *
X */
X#ifndef lint
Xstatic
Xchar rcs_hdr[] = "$Id: malloc_chn.c,v 1.4 90/05/11 00:13:09 cpcahil Exp $";
X#endif
X
X
Xint
Xmalloc_chain_check(todo)
X	int		  todo;
X{
X	char			* func = "malloc_chain_check";
X	int			  i;
X	extern char		* malloc_data_start;
X	extern char		* malloc_data_end;
X	extern struct mlist 	* malloc_end;
X	extern int		  malloc_errno;
X	extern struct mlist	  malloc_start;
X	struct mlist		* oldptr;
X	struct mlist		* ptr;
X	int			  rtn = 0;
X
X	oldptr = &malloc_start;
X	for(ptr = malloc_start.next; ; ptr = ptr->next)
X	{
X		/*
X		 * Since the malloc chain is a forward only chain, any
X		 * pointer that we get should always be positioned in 
X		 * memory following the previous pointer.  If this is not
X		 * so, we must have a corrupted chain.
X		 */
X		if( ptr )
X		{
X			if(ptr < oldptr )
X			{
X				malloc_errno = M_CODE_CHAIN_BROKE;
X				if( todo )
X				{
X					malloc_fatal(func);
X				}
X				rtn++;
X				break;
X			}
X			oldptr = ptr;
X		}
X		else
X		{
X			if( oldptr != malloc_end )
X			{
X				/*
X				 * This should never happen.  If it does, then
X				 * we got a real problem.
X				 */
X				malloc_errno = M_CODE_NO_END;
X				if( todo )
X				{
X					malloc_fatal(func);
X				}
X				rtn++;
X			}
X			break;
X		}
X		
X		/*
X		 * verify that ptr is within the malloc region...
X		 * since we started within the malloc chain this should never
X		 * happen.
X		 */
X
X		if( ((char *)ptr < malloc_data_start) ||
X		    ((char *)ptr > malloc_data_end) )
X		{
X			malloc_errno = M_CODE_BAD_PTR;
X			if( todo )
X			{
X				malloc_fatal(func);
X			}
X			rtn++;
X			break;
X		}
X
X		/* 
X		 * verify magic flag is set
X		 */
X		
X		if( (ptr->flag&M_MAGIC) != M_MAGIC )
X		{
X			malloc_errno = M_CODE_BAD_MAGIC;
X			if( todo )
X			{
X				malloc_warning(func);
X			}
X			rtn++;
X			continue;
X		}
X
X		/* 
X		 * verify segments are correctly linked together
X		 */
X		
X		if( (ptr->prev && (ptr->prev->next != ptr) ) ||
X		    (ptr->next && (ptr->next->prev != ptr) ) ||
X		    ((ptr->next == NULL) && (ptr->prev == NULL)) )
X		{
X			malloc_errno = M_CODE_BAD_CONNECT;
X			if( todo )
X			{
X				malloc_warning(func);
X			}
X			rtn++;
X			continue;
X		}
X
X		/*
X		 * If this segment is allocated
X		 */
X
X		if( (ptr->flag & M_INUSE) != 0 )
X		{
X			/*
X			 * verify no overflow of data area
X			 */
X
X			for(i=ptr->r_size; i < ptr->s.size; i++)
X			{
X				if( ptr->data[i] != M_FILL )
X				{
X					malloc_errno = M_CODE_OVERRUN;
X					if( todo )
X					{
X						malloc_warning(func);
X					}
X					rtn++;
X					break;
X				}
X			}
X		}
X		else /* it's not allocated so */
X		{
X			/*
X			 * verify no reuse of freed data blocks
X			 */
X
X			for(i=0; i < ptr->s.size; i++)
X			{
X				if( ptr->data[i] != M_FREE_FILL )
X				{
X					malloc_errno = M_CODE_REUSE;
X					if( todo )
X					{
X						malloc_warning(func);
X					}
X					rtn++;
X					break;
X				}
X			}
X		}
X
X	} /* for(... */
X
X	return(rtn);
X
X} /* malloc_chain_check(... */
SHAR_EOF
$TOUCH -am 0511001490 malloc_chn.c &&
chmod 0444 malloc_chn.c ||
echo "restore of malloc_chn.c failed"
set `wc -c malloc_chn.c`;Wc_c=$1
if test "$Wc_c" != "3449"; then
	echo original size 3449, current size $Wc_c
fi
fi
# ============= mallopt.c ==============
if test X"$1" != X"-c" -a -f 'mallopt.c'; then
	echo "File already exists: skipping 'mallopt.c'"
else
echo "x - extracting mallopt.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > mallopt.c &&
X/*
X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
X * You may copy, distribute, and use this software as long as this
X * copyright statement is not removed.
X */
X#include <stdio.h>
X#include <fcntl.h>
X#include "malloc.h"
X
X/*
X * Function:	mallopt()
X *
X * Purpose:	to set options for the malloc debugging library
X *
X * Arguments:	none
X *
X * Returns:	nothing of any value
X *
X * Narrative:	
X *
X */
X
X#ifndef lint
Xstatic
Xchar rcs_hdr[] = "$Id: mallopt.c,v 1.4 90/05/11 00:13:10 cpcahil Exp $";
X#endif
X
Xunion val
X{
X	int	  i;
X	char	* str;
X};
X
Xint
Xmallopt(cmd,value)
X	int			  cmd;
X	union val		  value;
X{
X	int			  i;
X	extern int		  malloc_checking;
X	extern char		* malloc_data_start;
X	extern int		  malloc_errfd;
X	extern int		  malloc_fatal_level;
X	void			  malloc_init();
X	extern int		  malloc_warn_level;
X	register char		* s;
X
X	/*
X 	 * If not initialized...
X	 */
X	if( malloc_data_start == (char *) 0)
X	{
X		malloc_init();
X	}
X
X
X	switch(cmd)
X	{
X		case MALLOC_WARN:
X			malloc_warn_level = value.i;
X			break;
X
X		case MALLOC_FATAL:
X			malloc_fatal_level = value.i;
X			break;
X
X		case MALLOC_CKCHAIN:
X			malloc_checking = value.i;
X			break;
X
X		case MALLOC_ERRFILE:
X			
X			i = open(value.str,O_CREAT|O_APPEND|O_WRONLY,0666);
X			if( i == -1 )
X			{
X				(void) write(2,
X					  "Unable to open malloc error file: ",
X					  (unsigned) 34);
X				for(s=value.str; *s; s++)
X				{
X					/* do nothing */;
X				}
X				(void) write(2,value.str,
X					     (unsigned)(s-value.str));
X				(void) write(2,"\n",(unsigned)1);
X			}
X			else
X			{
X				if( malloc_errfd != 2 )
X				{
X					(void) close(malloc_errfd);
X				}
X			}
X			
X			break;
X
X		default:
X			return(1);
X			break;
X	}
X
X	return(0);
X}
X
X/*
X * $Log:	mallopt.c,v $
X * Revision 1.4  90/05/11  00:13:10  cpcahil
X * added copyright statment
X * 
X * Revision 1.3  90/02/25  11:03:26  cpcahil
X * changed to return int so that it agrees with l libmalloc.a's mallopt()
X * 
X * Revision 1.2  90/02/25  11:01:21  cpcahil
X * added support for malloc chain checking.
X * 
X * Revision 1.1  90/02/24  21:50:24  cpcahil
X * Initial revision
X * 
X * Revision 1.1  90/02/24  17:10:53  cpcahil
X * Initial revision
X * 
X */
SHAR_EOF
$TOUCH -am 0511001490 mallopt.c &&
chmod 0444 mallopt.c ||
echo "restore of mallopt.c failed"
set `wc -c mallopt.c`;Wc_c=$1
if test "$Wc_c" != "2128"; then
	echo original size 2128, current size $Wc_c
fi
fi
# ============= memory.c ==============
if test X"$1" != X"-c" -a -f 'memory.c'; then
	echo "File already exists: skipping 'memory.c'"
else
echo "x - extracting memory.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > memory.c &&
X/*
X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
X * You may copy, distribute, and use this software as long as this
X * copyright statement is not removed.
X */
X
X#ifndef lint
Xstatic
Xchar rcs_hdr[] = "$Id: memory.c,v 1.5 90/05/11 15:39:36 cpcahil Exp $";
X#endif
X
Xchar *
Xmemccpy(ptr1, ptr2, ch, len)
X	register char	* ptr1;
X	register char	* ptr2;
X	int		  len;
X	int		  ch;
X{
X	int		  check;
X	register int	  i;
X	char		* rtn;
X
X	/*
X	 * I know that the assignment could be done in the following, but
X	 * I wanted to perform a check before any assignment, so first I 
X	 * determine the length, check the pointers and then do the assignment.
X	 */
X	for( i=0; (i < len) && (ptr2[i] != ch); i++)
X	{
X	}
X	if( ptr2[i] == ch )
X	{
X		check = i+1;
X	}
X
X	malloc_check_data("memccpy", ptr1, check);
X	malloc_check_data("memccpy", ptr2, check);
X
X	/*
X	 * if we found the character...
X 	 */
X
X	if( i < len )
X	{
X		rtn = ptr1+i+1;
X		i++;
X	}
X	else
X	{
X		rtn = (char *) 0;
X	}
X
X 	while( i-- )
X	{
X		*(ptr1++) = *(ptr2++);
X	}
X	
X	return(rtn);
X}
X
Xchar *
Xmemchr(ptr1,ch,len)
X	register char	* ptr1;
X	register int	  ch;
X	int		  len;
X{
X	int		  i;
X
X	for( i=0; (i < len) && (ptr1[i] != ch); i++)
X	{
X	}
X
X	malloc_check_data("memchr", ptr1, i);
X
X	if( i < len )
X	{
X		return( ptr1+i );
X	}
X	else
X	{
X		return( (char *) 0);	
X	}
X}
X
Xchar *
Xmemcpy(ptr1, ptr2, len)
X	register char	* ptr1;
X	register char	* ptr2;
X	register int	  len;
X{
X	char		* rtn = ptr1;
X
X	malloc_check_data("memcpy", ptr1, len);
X	malloc_check_data("memcpy", ptr2, len);
X	
X	while( len-- )
X	{
X		*(ptr1++) = *(ptr2++);
X	}
X	return(rtn);
X}
X
Xint
Xmemcmp(ptr1, ptr2, len)
X	register char	* ptr1;
X	register char	* ptr2;
X	register int	  len;
X{
X	malloc_check_data("memcpy", ptr1, len);
X	malloc_check_data("memcpy", ptr2, len);
X
X	while( --len && (*ptr1 == *ptr2) )
X	{
X		ptr1++;
X		ptr2++;
X	}
X	return( *ptr1 - *ptr2 );
X}
X
Xchar * 
Xmemset(ptr1, ch, len)
X	register char	* ptr1;
X	register int	  ch;
X	register int	  len;
X{
X	char		* rtn = ptr1;
X
X	malloc_check_data("memcpy", ptr1, len);
X
X	while( len-- )
X	{
X		*(ptr1++) = ch;
X	}
X
X	return(rtn);
X}
X
Xchar *
Xbcopy(ptr2,ptr1,len)
X	char		* ptr2;
X	char		* ptr1;
X	int		  len;
X{
X	return(memcpy(ptr1,ptr2,len));
X}
X
Xchar *
Xbzero(ptr1,len)
X	char		* ptr1;
X	int		  len;
X{
X	return(memset(ptr1,'\0',len));
X}
X
Xint
Xbcmp(ptr2, ptr1, len)
X	char		* ptr1;
X	char		* ptr2;
X	int		  len;
X{
X	return( memcmp(ptr1,ptr2,len) );
X}
X
X/*
X * $Log:	memory.c,v $
X * Revision 1.5  90/05/11  15:39:36  cpcahil
X * fixed bug in memccpy().
X * 
X * Revision 1.4  90/05/11  00:13:10  cpcahil
X * added copyright statment
X * 
X * Revision 1.3  90/02/24  21:50:29  cpcahil
X * lots of lint fixes
X * 
X * Revision 1.2  90/02/24  17:29:41  cpcahil
X * changed $Header to $Id so full path wouldnt be included as part of rcs 
X * id string
X * 
X * Revision 1.1  90/02/22  23:17:43  cpcahil
X * Initial revision
X * 
X */
SHAR_EOF
$TOUCH -am 0511153990 memory.c &&
chmod 0444 memory.c ||
echo "restore of memory.c failed"
set `wc -c memory.c`;Wc_c=$1
if test "$Wc_c" != "2817"; then
	echo original size 2817, current size $Wc_c
fi
fi
# ============= realloc.c ==============
if test X"$1" != X"-c" -a -f 'realloc.c'; then
	echo "File already exists: skipping 'realloc.c'"
else
echo "x - extracting realloc.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > realloc.c &&
X/*
X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
X * You may copy, distribute, and use this software as long as this
X * copyright statement is not removed.
X */
X#include <stdio.h>
X#include "malloc.h"
X
X/*
X * Function:	realloc()
X *
X * Purpose:	to re-allocate a data area.
X *
X * Arguments:	cptr	- pointer to area to reallocate
X *		size	- size to change area to
X *
X * Returns:	pointer to new area (may be same area)
X *
X * Narrative:	verify pointer is within malloc region
X *		obtain mlist pointer from cptr
X *		verify magic number is correct
X *		verify inuse flag is set
X *		verify connection to adjoining segments is correct
X *		save requested size
X *		round-up size to appropriate boundry
X *		IF size is bigger than what is in this segment
X *		    try to join next segment to this segment
X *		IF size is less than what is is this segment
X *		    determine leftover amount of space
X *		ELSE
X *		    allocate new segment of size bites
X *		    IF allocation failed
X *		        return NULL
X *		    copy previous data to new segment
X *		    free previous segment
X *		    return new pointer
X *		split of extra space in this segment (if any)
X *		clear bytes beyound what they had before
X *		return pointer to data 
X */
X#ifndef lint
Xstatic
Xchar rcs_hdr[] = "$Id: realloc.c,v 1.7 90/05/11 00:13:10 cpcahil Exp $";
X#endif
X
Xchar *
Xrealloc(cptr,size)
X	char			* cptr;
X	unsigned int		  size;
X{
X	void			  free();
X	char			* func = "realloc";
X	int			  i;
X	char			* malloc();
X	extern int		  malloc_checking;
X	extern struct mlist 	* malloc_end;
X	extern int		  malloc_errno;
X	extern char		* malloc_data_end;
X	extern char		* malloc_data_start;
X	char			* memcpy();
X	char			* new_cptr;
X	struct mlist		* ptr;
X	int			  r_size;
X
X	/*
X	 * IF malloc chain checking is on, go do it.
X	 */
X	if( malloc_checking )
X	{
X		(void) malloc_chain_check(1);
X	}
X
X	/*
X	 * verify that cptr is within the malloc region...
X	 */
X	if( cptr < malloc_data_start || cptr > malloc_data_end )
X	{
X		malloc_errno = M_CODE_BAD_PTR;
X		malloc_warning(func);
X		return (NULL);
X	}
X
X	/* 
X	 * convert pointer to mlist struct pointer.  To do this we must 
X	 * move the pointer backwards the correct number of bytes...
X	 */
X	
X	ptr = (struct mlist *) (cptr - M_SIZE);
X	
X	if( (ptr->flag&M_MAGIC) != M_MAGIC )
X	{
X		malloc_errno = M_CODE_BAD_MAGIC;
X		malloc_warning(func);
X		return(NULL);
X	}
X
X	if( ! (ptr->flag & M_INUSE) )
X	{
X		malloc_errno = M_CODE_NOT_INUSE ;
X		malloc_warning(func);
X		return(NULL);
X	}
X
X 	if( (ptr->prev && (ptr->prev->next != ptr) ) ||
X	    (ptr->next && (ptr->next->prev != ptr) ) ||
X	    ((ptr->next == NULL) && (ptr->prev == NULL)) )
X	{
X		malloc_errno = M_CODE_BAD_CONNECT;
X		malloc_warning(func);
X		return(NULL);
X	}
X
X	r_size = ++size;
X
X	M_ROUNDUP(size);
X
X	if( size > ptr->s.size )
X	{
X		malloc_join(ptr,ptr->next,1,1);
X	}
X
X	if( size > ptr->s.size )
X	{
X		/*
X		 * else we can't combine it, so lets allocate a new chunk,
X		 * copy the data and free the old chunk...
X		 */
X		new_cptr = malloc(size);
X
X		if( new_cptr == (char *) 0)
X		{
X			return(new_cptr);
X		}
X
X		if( r_size < ptr->r_size )
X		{
X			i = r_size;
X		}
X		else
X		{
X			i = ptr->r_size;
X		}
X		(void)memcpy(new_cptr,ptr->data,i);
X		free(cptr);
X		return(new_cptr);
X
X	} /* else... */
X
X	/*
X	 * save amount of real data in new segment (this will be used in the
X	 * memset later) and then save requested size of this segment.
X	 */
X
X	if( ptr->r_size < r_size )
X	{
X		i = ptr->r_size;
X	}
X	else
X	{
X		i = r_size;
X	}
X
X	ptr->r_size = r_size;
X
X	/*
X	 * split off extra free space at end of this segment, if possible...
X	 */
X
X	malloc_split(ptr);
X
X	malloc_memset( ptr->data+i, M_FILL, ptr->s.size - i);
X		
X	return(ptr->data);
X
X} /* realloc(... */
X
X
X/*
X * $Log:	realloc.c,v $
X * Revision 1.7  90/05/11  00:13:10  cpcahil
X * added copyright statment
X * 
X * Revision 1.6  90/02/25  11:01:20  cpcahil
X * added support for malloc chain checking.
X * 
X * Revision 1.5  90/02/24  21:50:31  cpcahil
X * lots of lint fixes
X * 
X * Revision 1.4  90/02/24  17:29:39  cpcahil
X * changed $Header to $Id so full path wouldnt be included as part of rcs 
X * id string
X * 
X * Revision 1.3  90/02/24  17:20:00  cpcahil
X * attempt to get rid of full path in rcs header.
X * 
X * Revision 1.2  90/02/24  15:14:20  cpcahil
X * 1. added function header 
X * 2. changed calls to malloc_warning to conform to new usage
X * 3. added setting of malloc_errno
X *  4. broke up bad pointer determination so that errno's would be more
X *    descriptive
X * 
X * Revision 1.1  90/02/22  23:17:43  cpcahil
X * Initial revision
X * 
X */
SHAR_EOF
$TOUCH -am 0511001490 realloc.c &&
chmod 0444 realloc.c ||
echo "restore of realloc.c failed"
set `wc -c realloc.c`;Wc_c=$1
if test "$Wc_c" != "4496"; then
	echo original size 4496, current size $Wc_c
fi
fi
# ============= string.c ==============
if test X"$1" != X"-c" -a -f 'string.c'; then
	echo "File already exists: skipping 'string.c'"
else
echo "x - extracting string.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > string.c &&
X/*
X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
X * You may copy, distribute, and use this software as long as this
X * copyright statement is not removed.
X */
X
X#include <stdio.h>
X#include <string.h>
X#include <sys/types.h>
X#include "malloc.h"
X
X#ifndef lint
Xstatic
Xchar rcs_hdr[] = "$Id: string.c,v 1.5 90/06/10 14:59:49 cpcahil Exp $";
X#endif
X
Xint	malloc_checking = 0;
X
Xchar *
Xstrcat(str1,str2)
X	register char	* str1;
X	register char	* str2;
X{
X	char		* rtn;
X	int	  len;
X
X	/* 
X	 * check pointers agains malloc region.  The malloc* functions
X	 * will properly handle the case where a pointer does not
X	 * point into malloc space.
X	 */
X	malloc_checking = 1;
X
X	len = strlen(str2);
X	malloc_check_str("strcat", str2);
X
X	len += strlen(str1) + 1;
X	malloc_checking = 0;
X
X	malloc_check_data("strcat", str1, len);
X
X	rtn = str1;
X
X	while( *str1 )
X	{
X		str1++;
X	}
X	
X	while( (*str1 = *str2) != '\0' )
X	{
X		str1++;
X		str2++;
X	}
X	
X	return(rtn);
X}
X
Xchar *
Xstrdup(str1)
X	register char	* str1;
X{
X	char		* malloc();
X	char		* rtn;
X	register char	* str2;
X
X	malloc_check_str("strdup", str1);
X
X	rtn = str2 = malloc((unsigned)strlen(str1)+1);
X
X	if( rtn != (char *) 0)
X	{
X		while( (*str2 = *str1) != '\0' )
X		{
X			str1++;
X			str2++;
X		}
X	}
X
X	return(rtn);
X}
X
Xchar *
Xstrncat(str1,str2,len)
X	register char	* str1;
X	register char	* str2;
X	register int	  len;
X{
X	int 		  len1;
X	int 		  len2;
X	char		* rtn;
X
X	malloc_checking = 1;
X
X	len2 = strlen(str2) + 1;
X	len1 = strlen(str1);
X
X	malloc_checking = 0;
X
X	malloc_check_data("strncat", str2,len2);
X
X	if( (len+1) < len2 )
X	{
X		len1 += len + 1;
X	}
X	else
X	{
X		len1 += len2;
X	}
X	malloc_check_data("strncat", str1, len1);
X
X	rtn = str1;
X
X	while( *str1 )
X	{
X		str1++;
X	}
X
X	while( len-- && ((*str1++ = *str2++) != '\0') )
X	{
X	}
X	
X	if( ! len )
X	{
X		*str1 = '\0';
X	}
X
X	return(rtn);
X}
X
Xint
Xstrcmp(str1,str2)
X	register char	* str1;
X	register char	* str2;
X{
X	malloc_check_str("strcmp", str1);
X	malloc_check_str("strcmp", str2);
X
X	while( *str1 && (*str1 == *str2) )
X	{
X		str1++;
X		str2++;
X	}
X	return( *str1 - *str2 );
X}
X
Xint
Xstrncmp(str1,str2,len)
X	register char	* str1;
X	register char	* str2;
X	register int	  len;
X{
X	malloc_check_str("strncmp", str1);
X	malloc_check_str("strncmp", str2);
X
X	while( --len && *str1 && (*str1 == *str2) )
X	{
X		str1++;
X		str2++;
X	}
X	return( *str1 - *str2 );
X}
X
Xchar *
Xstrcpy(str1,str2)
X	register char	* str1;
X	register char	* str2;
X{
X	char		* rtn;
X	int		  len;
X
X	malloc_checking = 1;
X	len = strlen(str2) + 1;
X	malloc_checking = 0;
X
X	malloc_check_data("strcpy", str1, len);
X	malloc_check_data("strcpy", str2, len);
X
X	rtn = str1;
X
X	while( (*str1++ = *str2++) != '\0')
X	{
X	}
X
X	return(rtn);
X}
X
Xchar *
Xstrncpy(str1,str2,len)
X	register char	* str1;
X	register char	* str2;
X	register int	  len;
X{
X	int		  i;
X	extern int	  malloc_checking;
X	char		* rtn;
X
X	malloc_check_data("strncpy", str1, len);
X
X	malloc_checking = 1;
X	i = strlen(str2);
X	malloc_checking = 0;
X
X	if( i > len )
X	{
X		i = len;
X	}
X
X	malloc_check_data("strncpy", str2, i);
X
X	rtn = str1;
X
X	while((len-- > 0) && (*str1++ = *str2++) != '\0')
X	{
X	}
X	while( (len-- > 0) )
X	{
X		*str1++ = '\0';
X	}
X
X	return(rtn);
X}
X
Xint
Xstrlen(str1)
X	register char	* str1;
X{
X	register char	* s;
X
X	if(! malloc_checking )
X	{
X		malloc_check_str("strlen", str1);
X	}
X
X	for( s = str1; *s; s++)
X	{
X	}
X
X	return( s - str1 );
X}
X
Xchar *
Xstrchr(str1,c)
X	register char	* str1;
X	register int	  c;
X{
X	malloc_check_str("strchr", str1);
X
X	while( *str1 && (*str1 != (char) c) )
X	{
X		str1++;
X	}
X
X	if(! *str1 )
X	{
X		str1 = (char *) 0;
X	}
X
X	return(str1);
X}
X
Xchar *
Xstrrchr(str1,c)
X	register char	* str1;
X	register int	  c;
X{
X	register char	* rtn = (char *) 0;
X
X	malloc_check_str("strrchr", str1);
X
X	while( *str1 )
X	{
X		if(*str1 == (char) c )
X		{
X			rtn = str1;
X		}
X		str1++;
X	}
X
X	return(rtn);
X}
X
Xchar *
Xindex(str1,c)
X	char		* str1;
X	char		  c;
X{
X	return( strchr(str1,c) );
X}
X
Xchar *
Xrindex(str1,c)
X	char		* str1;
X	char		  c;
X{
X	return( strrchr(str1,c) );
X}
X
Xchar *
Xstrpbrk(str1,str2)
X	register char	* str1;
X	register char	* str2;
X{
X	register char	* tmp;
X
X	malloc_check_str("strpbrk", str1);
X	malloc_check_str("strpbrk", str2);
X
X	while(*str1)
X	{
X		for( tmp=str2; *tmp && *tmp != *str1; tmp++)
X		{
X		}
X		if( *tmp )
X		{
X			break;
X		}
X		str1++;
X	}
X
X	if( ! *str1 )
X	{
X		str1 = (char *) 0;
X	}
X
X	return(str1);
X}
X
Xint
Xstrspn(str1,str2)
X	register char	* str1;
X	register char	* str2;
X{
X	register char	* tmp;
X	char		* orig = str1;
X
X	malloc_check_str("strspn", str1);
X	malloc_check_str("strspn", str2);
X
X	while(*str1)
X	{
X		for( tmp=str2; *tmp && *tmp != *str1; tmp++)
X		{
X		}
X		if(! *tmp )
X		{
X			break;
X		}
X		str1++;
X	}
X
X	return( (int) (str1 - orig) );
X}
X
Xint
Xstrcspn(str1,str2)
X	register char	* str1;
X	register char	* str2;
X{
X	register char	* tmp;
X	char		* orig = str1;
X
X	malloc_check_str("strcspn", str1);
X	malloc_check_str("strcspn", str2);
X
X	while(*str1)
X	{
X		for( tmp=str2; *tmp && *tmp != *str1; tmp++)
X		{
X		}
X		if( *tmp )
X		{
X			break;
X		}
X		str1++;
X	}
X
X	return( (int) (str1 - orig) );
X}
X
X/*
X * strtok() source taken from that posted to comp.lang.c by Chris Torek
X * in Jan 1990.
X */
X
X/*
X * Copyright (c) 1989 The Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that the above copyright notice and this paragraph are
X * duplicated in all such forms and that any documentation,
X * advertising materials, and other materials related to such
X * distribution and use acknowledge that the software was developed
X * by the University of California, Berkeley.  The name of the
X * University may not be used to endorse or promote products derived
X * from this software without specific prior written permission.
X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X */
X
X/*
X * Get next token from string s (NULL on 2nd, 3rd, etc. calls),
X * where tokens are nonempty strings separated by runs of
X * chars from delim.  Writes NULs into s to end tokens.  delim need not
X * remain constant from call to call.
X *
X * Modified by cpc: 	changed variable names to conform with naming
X *			conventions used in rest of code.  Added malloc pointer
X *			check calls.
X */
Xchar *
Xstrtok(str1, str2)
X	char 	* str1;
X	char	* str2;
X{
X	static char 	* last;
X	char		* strtoken();
X
X	if( str1 )
X	{
X		malloc_check_str("strtok", str1);
X		last = str1;
X	}
X	malloc_check_str("strtok", str2);
X
X	return (strtoken(&last, str2, 1));
X}
X
X
X/*
X * Get next token from string *stringp, where tokens are (possibly empty)
X * strings separated by characters from delim.  Tokens are separated
X * by exactly one delimiter iff the skip parameter is false; otherwise
X * they are separated by runs of characters from delim, because we
X * skip over any initial `delim' characters.
X *
X * Writes NULs into the string at *stringp to end tokens.
X * delim will usually, but need not, remain constant from call to call.
X * On return, *stringp points past the last NUL written (if there might
X * be further tokens), or is NULL (if there are definitely no more tokens).
X *
X * If *stringp is NULL, strtoken returns NULL.
X */
Xchar *
Xstrtoken(stringp, delim, skip)
X	register char **stringp;
X	register char *delim;
X	int skip;
X{
X	register char *s;
X	register char *spanp;
X	register int c, sc;
X	char *tok;
X
X	if ((s = *stringp) == NULL)
X		return (NULL);
X
X	if (skip) {
X		/*
X		 * Skip (span) leading delimiters (s += strspn(s, delim)).
X		 */
X	cont:
X		c = *s;
X		for (spanp = delim; (sc = *spanp++) != 0;) {
X			if (c == sc) {
X				s++;
X				goto cont;
X			}
X		}
X		if (c == 0) {		/* no token found */
X			*stringp = NULL;
X			return (NULL);
X		}
X	}
X
X	/*
X	 * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
X	 * Note that delim must have one NUL; we stop if we see that, too.
X	 */
X	for (tok = s;;) {
X		c = *s++;
X		spanp = delim;
X		do {
X			if ((sc = *spanp++) == c) {
X				if (c == 0)
X					s = NULL;
X				else
X					s[-1] = 0;
X				*stringp = s;
X				return (tok);
X			}
X		} while (sc != 0);
X	}
X	/* NOTREACHED */
X}
X
X/*
X * $Log:	string.c,v $
X * Revision 1.5  90/06/10  14:59:49  cpcahil
X * Fixed a couple of bugs in strncpy & strdup
X * 
X * Revision 1.4  90/05/11  00:13:10  cpcahil
X * added copyright statment
X * 
X * Revision 1.3  90/02/24  21:50:32  cpcahil
X * lots of lint fixes
X * 
X * Revision 1.2  90/02/24  17:29:40  cpcahil
X * changed $Header to $Id so full path wouldnt be included as part of rcs 
X * id string
X * 
X * Revision 1.1  90/02/22  23:17:44  cpcahil
X * Initial revision
X * 
X */
SHAR_EOF
$TOUCH -am 0610150290 string.c &&
chmod 0444 string.c ||
echo "restore of string.c failed"
set `wc -c string.c`;Wc_c=$1
if test "$Wc_c" != "8521"; then
	echo original size 8521, current size $Wc_c
fi
fi
# ============= testmalloc.c ==============
if test X"$1" != X"-c" -a -f 'testmalloc.c'; then
	echo "File already exists: skipping 'testmalloc.c'"
else
echo "x - extracting testmalloc.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > testmalloc.c &&
X/* NOT copyright by SoftQuad Inc. -- msb, 1988 */
X#ifndef lint
Xstatic char *SQ_SccsId = "@(#)mtest3.c	1.2 88/08/25";
X#endif
X#include <stdio.h>
X/*
X** looptest.c -- intensive allocator tester 
X**
X** Usage:  looptest
X**
X** History:
X**	4-Feb-1987 rtech!daveb 
X*/
X
X# ifdef SYS5
X# define random	rand
X# else
X# include <sys/vadvise.h>
X# endif
X
X# include <stdio.h>
X# include <signal.h>
X# include <setjmp.h>
X
X# define MAXITER	1000000		/* main loop iterations */
X# define MAXOBJS	1000		/* objects in pool */
X# define BIGOBJ		90000		/* max size of a big object */
X# define TINYOBJ	80		/* max size of a small object */
X# define BIGMOD		100		/* 1 in BIGMOD is a BIGOBJ */
X# define STATMOD	10000		/* interation interval for status */
X
Xmain( argc, argv )
Xint argc;
Xchar **argv;
X{
X	register int **objs;		/* array of objects */
X	register int *sizes;		/* array of object sizes */
X	register int n;			/* iteration counter */
X	register int i;			/* object index */
X	register int size;		/* object size */
X	register int r;			/* random number */
X
X	int objmax;			/* max size this iteration */
X	int cnt;			/* number of allocated objects */
X	int nm = 0;			/* number of mallocs */
X	int nre = 0;			/* number of reallocs */
X	int nal;			/* number of allocated objects */
X	int nfre;			/* number of free list objects */
X	long alm;			/* memory in allocated objects */
X	long frem;			/* memory in free list */
X	long startsize;			/* size at loop start */
X	long endsize;			/* size at loop exit */
X	long maxiter = 0;		/* real max # iterations */
X
X	extern char end;		/* memory before heap */
X	char *calloc();
X	char *malloc();
X	char *sbrk();
X	long atol();
X
X# ifndef SYS5
X	/* your milage may vary... */
X	vadvise( VA_ANOM );
X# endif
X
X	if (argc > 1)
X		maxiter = atol (argv[1]);
X	if (maxiter <= 0)
X		maxiter = MAXITER;
X
X	printf("MAXITER %d MAXOBJS %d ", maxiter, MAXOBJS );
X	printf("BIGOBJ %d, TINYOBJ %d, nbig/ntiny 1/%d\n",
X	BIGOBJ, TINYOBJ, BIGMOD );
X	fflush( stdout );
X
X	if( NULL == (objs = (int **)calloc( MAXOBJS, sizeof( *objs ) ) ) )
X	{
X		fprintf(stderr, "Can't allocate memory for objs array\n");
X		exit(1);
X	}
X
X	if( NULL == ( sizes = (int *)calloc( MAXOBJS, sizeof( *sizes ) ) ) )
X	{
X		fprintf(stderr, "Can't allocate memory for sizes array\n");
X		exit(1);
X	}
X
X	/* as per recent discussion on net.lang.c, calloc does not 
X	** necessarily fill in NULL pointers...
X	*/
X	for( i = 0; i < MAXOBJS; i++ )
X		objs[ i ] = NULL;
X
X	startsize = sbrk(0) - &end;
X	printf( "Memory use at start: %d bytes\n", startsize );
X	fflush(stdout);
X
X	printf("Starting the test...\n");
X	fflush(stdout);
X	for( n = 0; n < maxiter ; n++ )
X	{
X		if( !(n % STATMOD) )
X		{
X			printf("%d iterations\n", n);
X			fflush(stdout);
X		}
X
X		/* determine object of interst and it's size */
X
X		r = random();
X		objmax = ( r % BIGMOD ) ? TINYOBJ : BIGOBJ;
X		size = r % objmax;
X		i = r % (MAXOBJS - 1);
X
X		/* either replace the object of get a new one */
X
X		if( objs[ i ] == NULL )
X		{
X			objs[ i ] = (int *)malloc( size );
X			nm++;
X		}
X		else
X		{
X			/* don't keep bigger objects around */
X			if( size > sizes[ i ] )
X			{
X				objs[ i ] = (int *)realloc( objs[ i ], size );
X				nre++;
X			}
X			else
X			{
X				free( objs[ i ] );
X				objs[ i ] = (int *)malloc( size );
X				nm++;
X			}
X		}
X
X		sizes[ i ] = size;
X		if( objs[ i ] == NULL )
X		{
X			printf("\nCouldn't allocate %d byte object!\n", 
X				size );
X			break;
X		}
X	} /* for() */
X
X	printf( "\n" );
X	cnt = 0;
X	for( i = 0; i < MAXOBJS; i++ )
X		if( objs[ i ] )
X			cnt++;
X
X	printf( "Did %d iterations, %d objects, %d mallocs, %d reallocs\n",
X		n, cnt, nm, nre );
X	printf( "Memory use at end: %d bytes\n", sbrk(0) - &end );
X	fflush( stdout );
X
X	/* free all the objects */
X	for( i = 0; i < MAXOBJS; i++ )
X		if( objs[ i ] != NULL )
X			free( objs[ i ] );
X
X	endsize = sbrk(0) - &end;
X	printf( "Memory use after free: %d bytes\n", endsize );
X	fflush( stdout );
X
X	if( startsize != endsize )
X		printf("startsize %d != endsize %d\n", startsize, endsize );
X
X	free( objs );
X	free( sizes );
X
X	malloc_dump(2);
X	exit( 0 );
X}
X
SHAR_EOF
$TOUCH -am 0511175990 testmalloc.c &&
chmod 0444 testmalloc.c ||
echo "restore of testmalloc.c failed"
set `wc -c testmalloc.c`;Wc_c=$1
if test "$Wc_c" != "3971"; then
	echo original size 3971, current size $Wc_c
fi
fi
# ============= testmem.c ==============
if test X"$1" != X"-c" -a -f 'testmem.c'; then
	echo "File already exists: skipping 'testmem.c'"
else
echo "x - extracting testmem.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > testmem.c &&
X/*
X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
X * You may copy, distribute, and use this software as long as this
X * copyright statement is not removed.
X */
X
X/* 
X * I have only partially implemented these tests.  If you have the time and
X * energy and wish to add some tests, feel free to do so.  I would appreciate
X * it if you sent me a copy of the modified files. 
X */
X
X#include <stdio.h>
X
X/* 
X * These tests test the memory functions...
X */
X
Xmain()
X{
X	char	  buffer[500];
X	int	  exitval = 0;
X	char	* memccpy();
X	char	* memchr();
X	char	* ptr1;
X	char	* ptr2;
X
X	fprintf(stdout,"Begining memory(3) tests...\n");
X
X	/*
X 	 * test memccpy()...
X 	 */
X
X	ptr1 = "abcdefghijklmn";	
X
X	buffer[0] = 'n';
X	buffer[1] = 'o';
X	buffer[2] = 'p';
X	buffer[3] = 'q'; 
X	buffer[4] = 'r';
X	buffer[5] = 's';
X	ptr2 = memccpy(buffer,ptr1,'d',3);
X
X	if( ptr2 != (char *) 0)
X	{
X		fprintf(stdout,"memccpy() failed to use passed length\n");
X		exitval++;
X	}
X
X	/*
X 	 * verify that the correct bytes got copied and the others do not
X	 * get clobbered
X	 */
X	if( (buffer[0] != 'a') ||
X	    (buffer[1] != 'b') ||
X	    (buffer[2] != 'c') ||
X	    (buffer[3] != 'q') ||
X	    (buffer[4] != 'r') ||
X	    (buffer[5] != 's')  )
X	{
X		fprintf(stdout,"memccpy() failed to copy bytes correctly\n");
X		fprintf(stdout,"Should have been 'abcqrs' was '%6.6s'\n",buffer);
X		exitval++;
X	}
X
X
X
X	buffer[0] = 'n';
X	buffer[1] = 'o';
X	buffer[2] = 'p';
X	buffer[3] = 'q'; 
X	buffer[4] = 'r';
X	buffer[5] = 's';
X	ptr2 = memccpy(buffer,ptr1,'d',4);
X
X	if( ptr2 != (buffer+4) )
X	{
X		fprintf(stdout,"memccpy() failed to find byte in data\n");
X		exitval++;
X	}
X
X	/*
X 	 * verify that the correct bytes got copied and the others do not
X	 * get clobbered
X	 */
X	if( (buffer[0] != 'a') ||
X	    (buffer[1] != 'b') ||
X	    (buffer[2] != 'c') ||
X	    (buffer[3] != 'd') ||
X	    (buffer[4] != 'r') ||
X	    (buffer[5] != 's')  )
X	{
X		fprintf(stdout,"memccpy() failed to copy bytes correctly\n");
X		fprintf(stdout,"Should have been 'abcdrs' was '%6.6s'\n",buffer);
X		exitval++;
X	}
X
X	/*
X	 * Test memchr()...
X	 */
X
X	ptr1 = "abcdefghijklmn";
X
X	ptr2 = memchr(ptr1,'c',10);
X	
X	if( ptr2 != (ptr1+2) )
X	{
X		fprintf(stdout,"memchr() failed to find byte in data\n");
X		exitval++;
X	}
X
X	ptr2 = memchr(ptr1,'j',10);
X	
X	if( ptr2 != (ptr1+9) )
X	{
X		fprintf(stdout,"memchr() failed to find byte in data\n");
X		exitval++;
X	}
X
X	ptr2 = memchr(ptr1,'k',10);
X	
X	if( ptr2 != (char *) 0)
X	{
X		fprintf(stdout,"memchr() failed to obey length argument\n");
X		exitval++;
X	}
X
X	fprintf(stdout,"Memory tests complete!\n");
X	exit(exitval);
X
X}
SHAR_EOF
$TOUCH -am 0511153990 testmem.c &&
chmod 0444 testmem.c ||
echo "restore of testmem.c failed"
set `wc -c testmem.c`;Wc_c=$1
if test "$Wc_c" != "2552"; then
	echo original size 2552, current size $Wc_c
fi
fi
# ============= tostring.c ==============
if test X"$1" != X"-c" -a -f 'tostring.c'; then
	echo "File already exists: skipping 'tostring.c'"
else
echo "x - extracting tostring.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > tostring.c &&
X/*
X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
X * You may copy, distribute, and use this software as long as this
X * copyright statement is not removed.
X */
X#include "tostring.h"
X
X/*
X * Function:	tostring()
X *
X * Purpose:	to convert an integer to an ascii display string
X *
X * Arguments:	buf	- place to put the 
X *		val	- integer to convert
X *		len	- length of output field (0 if just enough to hold data)
X *		base	- base for number conversion (only works for base <= 16)
X *		fill	- fill char when len > # digits
X *
X * Returns:	length of string
X *
X * Narrative:	IF fill character is non-blank
X *		    Determine base
X *		        If base is HEX
X *		            add "0x" to begining of string
X *		        IF base is OCTAL
X *		            add "0" to begining of string
X *
X *		While value is greater than zero
X *		    use val % base as index into xlation str to get cur char
X *		    divide val by base
X *
X *		Determine fill-in length
X *
X *		Fill in fill chars
X *
X *		Copy in number
X *		
X *
X * Mod History:	
X *   90/01/24	cpcahil		Initial revision.
X */
X
X#ifndef lint
Xstatic
Xchar rcs_hdr[] = "$Id: tostring.c,v 1.4 90/05/11 00:13:11 cpcahil Exp $";
X#endif
X
X#define T_LEN 10
X
Xint
Xtostring(buf,val,len,base,fill)
X	int	  base;
X	char	* buf;
X	char	  fill;
X	int	  len;
X	int	  val;
X	
X{
X	char	* bufstart = buf;
X	int	  i = T_LEN;
X	char	* xbuf = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
X	char	  tbuf[T_LEN];
X
X	/*
X	 * if we are filling with non-blanks, make sure the
X	 * proper start string is added
X	 */
X	if( fill != ' ' )
X	{
X		switch(base)
X		{
X			case B_HEX:
X				*(buf++) = '0';
X				*(buf++) = 'x';
X				if( len )
X				{
X					len -= 2;
X				}
X				break;
X			case B_OCTAL:
X				*(buf++) = fill;
X				if( len )
X				{
X					len--;
X				}
X				break;
X			default:
X				break;
X		}
X	}
X
X	while( val > 0 )
X	{
X		tbuf[--i] = xbuf[val % base];
X		val = val / base;
X	}
X
X	if( len )
X	{
X		len -= (T_LEN - i);
X
X		if( len > 0 )
X		{
X			while(len-- > 0)
X			{
X				*(buf++) = fill;
X			}
X		}
X		else
X		{
X			/* 
X			 * string is too long so we must truncate
X			 * off some characters.  We do this the easiest
X			 * way by just incrementing i.  This means the
X			 * most significant digits are lost.
X			 */
X			while( len++ < 0 )
X			{
X				i++;
X			}
X		}
X	}
X
X	while( i < T_LEN )
X	{
X		*(buf++) = tbuf[i++];
X	}
X
X	return( (int) (buf - bufstart) );
X
X} /* tostring(... */
X
X/*
X * $Log:	tostring.c,v $
X * Revision 1.4  90/05/11  00:13:11  cpcahil
X * added copyright statment
X * 
X * Revision 1.3  90/02/24  21:50:33  cpcahil
X * lots of lint fixes
X * 
X * Revision 1.2  90/02/24  17:29:42  cpcahil
X * changed $Header to $Id so full path wouldnt be included as part of rcs 
X * id string
X * 
X * Revision 1.1  90/02/22  23:17:44  cpcahil
X * Initial revision
X * 
X */
SHAR_EOF
$TOUCH -am 0511001490 tostring.c &&
chmod 0444 tostring.c ||
echo "restore of tostring.c failed"
set `wc -c tostring.c`;Wc_c=$1
if test "$Wc_c" != "2716"; then
	echo original size 2716, current size $Wc_c
fi
fi
# ============= tostring.h ==============
if test X"$1" != X"-c" -a -f 'tostring.h'; then
	echo "File already exists: skipping 'tostring.h'"
else
echo "x - extracting tostring.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > tostring.h &&
X/*
X * (c) Copyright 1990 Conor P. Cahill (uunet!virtech!cpcahil).  
X * You may copy, distribute, and use this software as long as this
X * copyright statement is not removed.
X */
X/*
X * $Id: tostring.h,v 1.2 90/05/11 00:13:11 cpcahil Exp $
X */
X#define B_BIN	 2
X#define B_DEC	10
X#define B_HEX	16
X#define B_OCTAL	 8
X
X/* 
X * $Log:	tostring.h,v $
X * Revision 1.2  90/05/11  00:13:11  cpcahil
X * added copyright statment
X * 
X * Revision 1.1  90/02/23  07:09:05  cpcahil
X * Initial revision
X * 
X */
SHAR_EOF
$TOUCH -am 0511001490 tostring.h &&
chmod 0444 tostring.h ||
echo "restore of tostring.h failed"
set `wc -c tostring.h`;Wc_c=$1
if test "$Wc_c" != "491"; then
	echo original size 491, current size $Wc_c
fi
fi
exit 0

-- 
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.



More information about the Comp.sources.unix mailing list