v19i027: dmake - dmake version 3.7, Part06/37
Dennis Vadura
dvadura at watdragon.waterloo.edu
Sat May 11 04:54:41 AEST 1991
Submitted-by: Dennis Vadura <dvadura at watdragon.waterloo.edu>
Posting-number: Volume 19, Issue 27
Archive-name: dmake/part06
Supersedes: dmake-3.6: Volume 15, Issue 52-77
---- Cut Here and feed the following to sh ----
#!/bin/sh
# this is dmake.shar.06 (part 6 of a multipart archive)
# do not concatenate these parts, unpack them in order with /bin/sh
# file dmake/dbug/malloc/mallopt.c continued
#
if test ! -r _shar_seq_.tmp; then
echo 'Please unpack part 1 first!'
exit 1
fi
(read Scheck
if test "$Scheck" != 6; then
echo Please unpack part "$Scheck" next!
exit 1
else
exit 0
fi
) < _shar_seq_.tmp || exit 1
if test -f _shar_wnt_.tmp; then
sed 's/^X//' << 'SHAR_EOF' >> 'dmake/dbug/malloc/mallopt.c' &&
X * You may copy, distribute, and use this software as long as this
X * copyright statement is not removed.
X */
#include <stdio.h>
#include <fcntl.h>
#include "malloc.h"
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
#ifndef lint
static
char rcs_hdr[] = "$Id: mallopt.c,v 1.6 90/08/29 22:23:36 cpcahil Exp $";
#endif
X
int
mallopt(cmd,value)
X int cmd;
X union malloptarg value;
{
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 malloc_errfd = i;
X }
X
X break;
X
X default:
X return(1);
X }
X
X return(0);
}
X
/*
X * $Log: mallopt.c,v $
X * Revision 1.6 90/08/29 22:23:36 cpcahil
X * fixed mallopt to use a union as an argument.
X *
X * Revision 1.5 90/08/29 21:22:51 cpcahil
X * miscellaneous lint fixes
X *
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
chmod 0640 dmake/dbug/malloc/mallopt.c ||
echo 'restore of dmake/dbug/malloc/mallopt.c failed'
Wc_c="`wc -c < 'dmake/dbug/malloc/mallopt.c'`"
test 2281 -eq "$Wc_c" ||
echo 'dmake/dbug/malloc/mallopt.c: original size 2281, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= dmake/dbug/malloc/memory.c ==============
if test -f 'dmake/dbug/malloc/memory.c' -a X"$1" != X"-c"; then
echo 'x - skipping dmake/dbug/malloc/memory.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
sed 's/^X//' << 'SHAR_EOF' > 'dmake/dbug/malloc/memory.c' &&
/*
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
#ifndef lint
static
char rcs_hdr[] = "$Id: memory.c,v 1.7 90/08/29 21:27:58 cpcahil Exp $";
#endif
X
void malloc_check_data();
X
char *
memccpy(ptr1, ptr2, ch, len)
X register char * ptr1;
X register char * ptr2;
X int len;
X int ch;
{
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 else
X {
X check = len;
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
char *
memchr(ptr1,ch,len)
X register char * ptr1;
X register int ch;
X int len;
{
X int i;
X
X for( i=0; (i < len) && (ptr1[i] != (char) 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
char *
memcpy(ptr1, ptr2, len)
X register char * ptr1;
X register char * ptr2;
X register int len;
{
X char * rtn = ptr1;
X
X malloc_check_data("memcpy", ptr1, len);
X malloc_check_data("memcpy", ptr2, len);
X
X /*
X * while the normal memcpy does not guarrantee that it will
X * handle overlapping memory correctly, we will try...
X */
X if( ptr1 > ptr2 && ptr1 < (ptr2+len))
X {
X ptr1 += (len-1);
X ptr2 += (len-1);
X while( len-- > 0 )
X {
X *(ptr1--) = *(ptr2--);
X }
X }
X else
X {
X while( len-- > 0 )
X {
X *(ptr1++) = *(ptr2++);
X }
X }
X
X return(rtn);
}
X
int
memcmp(ptr1, ptr2, len)
X register char * ptr1;
X register char * ptr2;
X register int len;
{
X malloc_check_data("memcpy", ptr1, len);
X malloc_check_data("memcpy", ptr2, len);
X
X while( --len >= 0 && (*ptr1 == *ptr2) )
X {
X ptr1++;
X ptr2++;
X }
X
X /*
X * If stopped by len, return zero
X */
X if( len < 0 )
X {
X return(0);
X }
X
X return( *ptr1 - *ptr2 );
}
X
char *
memset(ptr1, ch, len)
X register char * ptr1;
X register int ch;
X register int len;
{
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
char *
bcopy(ptr2,ptr1,len)
X char * ptr2;
X char * ptr1;
X int len;
{
X return(memcpy(ptr1,ptr2,len));
}
X
char *
bzero(ptr1,len)
X char * ptr1;
X int len;
{
X return(memset(ptr1,'\0',len));
}
X
int
bcmp(ptr2, ptr1, len)
X char * ptr1;
X char * ptr2;
X int len;
{
X return( memcmp(ptr1,ptr2,len) );
}
X
/*
X * $Log: memory.c,v $
X * Revision 1.7 90/08/29 21:27:58 cpcahil
X * fixed value of check in memccpy when character was not found.
X *
X * Revision 1.6 90/07/16 20:06:26 cpcahil
X * fixed several minor bugs found with Henry Spencer's string/mem tester
X * program.
X *
X *
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
chmod 0640 dmake/dbug/malloc/memory.c ||
echo 'restore of dmake/dbug/malloc/memory.c failed'
Wc_c="`wc -c < 'dmake/dbug/malloc/memory.c'`"
test 3505 -eq "$Wc_c" ||
echo 'dmake/dbug/malloc/memory.c: original size 3505, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= dmake/dbug/malloc/mlc_chk.c ==============
if test -f 'dmake/dbug/malloc/mlc_chk.c' -a X"$1" != X"-c"; then
echo 'x - skipping dmake/dbug/malloc/mlc_chk.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
sed 's/^X//' << 'SHAR_EOF' > 'dmake/dbug/malloc/mlc_chk.c' &&
/*
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>
#include "malloc.h"
#include "debug.h"
X
#ifndef lint
static
char rcs_hdr[] = "$Id: malloc_chk.c,v 1.5 90/08/29 22:23:48 cpcahil Exp $";
#endif
X
extern struct mlist malloc_start;
extern struct mlist * malloc_end;
extern char * malloc_data_start;
extern char * malloc_data_end;
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 */
int
malloc_in_arena(ptr)
X char * ptr;
{
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 * 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 */
void
malloc_check_str(func,str)
X char * func;
X char * str;
{
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 * Function: malloc_check_strn()
X *
X * Arguments: func - name of function calling this routine
X * str - pointer to area to check
X * len - max length of string
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 * 90/08/29 cpcahil added length (for strn* functions)
X */
void
malloc_check_strn(func,str,len)
X char * func;
X char * str;
X int len;
{
X register int i;
X static int layers;
X register char * s;
X
X if( (layers++ == 0) && malloc_in_arena(str) )
X {
X for( s=str,i=0; (i < len) && *s; s++)
X {
X }
X
X malloc_verify(func,str,s-str+1);
X }
X
X layers--;
}
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 */
void
malloc_check_data(func,ptr,len)
X char * func;
X char * ptr;
X int len;
{
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 * 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 */
void
malloc_verify(func,ptr,len)
X char * func;
X char * ptr;
X int len;
{
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 * $Log: malloc_chk.c,v $
X * Revision 1.5 90/08/29 22:23:48 cpcahil
X * added new function to check on strings up to a specified length
X * and used it within several strn* functions.
X *
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
chmod 0640 dmake/dbug/malloc/mlc_chk.c ||
echo 'restore of dmake/dbug/malloc/mlc_chk.c failed'
Wc_c="`wc -c < 'dmake/dbug/malloc/mlc_chk.c'`"
test 6308 -eq "$Wc_c" ||
echo 'dmake/dbug/malloc/mlc_chk.c: original size 6308, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= dmake/dbug/malloc/mlc_chn.c ==============
if test -f 'dmake/dbug/malloc/mlc_chn.c' -a X"$1" != X"-c"; then
echo 'x - skipping dmake/dbug/malloc/mlc_chn.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
sed 's/^X//' << 'SHAR_EOF' > 'dmake/dbug/malloc/mlc_chn.c' &&
/*
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 */
#include <stdio.h>
#include <fcntl.h>
#include "malloc.h"
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 */
#ifndef lint
static
char rcs_hdr[] = "$Id: malloc_chn.c,v 1.4 90/05/11 00:13:09 cpcahil Exp $";
#endif
X
X
int
malloc_chain_check(todo)
X int todo;
{
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
} /* malloc_chain_check(... */
SHAR_EOF
chmod 0640 dmake/dbug/malloc/mlc_chn.c ||
echo 'restore of dmake/dbug/malloc/mlc_chn.c failed'
Wc_c="`wc -c < 'dmake/dbug/malloc/mlc_chn.c'`"
test 3449 -eq "$Wc_c" ||
echo 'dmake/dbug/malloc/mlc_chn.c: original size 3449, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= dmake/dbug/malloc/patchlevel ==============
if test -f 'dmake/dbug/malloc/patchlevel' -a X"$1" != X"-c"; then
echo 'x - skipping dmake/dbug/malloc/patchlevel (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
sed 's/^X//' << 'SHAR_EOF' > 'dmake/dbug/malloc/patchlevel' &&
3
SHAR_EOF
chmod 0640 dmake/dbug/malloc/patchlevel ||
echo 'restore of dmake/dbug/malloc/patchlevel failed'
Wc_c="`wc -c < 'dmake/dbug/malloc/patchlevel'`"
test 2 -eq "$Wc_c" ||
echo 'dmake/dbug/malloc/patchlevel: original size 2, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= dmake/dbug/malloc/realloc.c ==============
if test -f 'dmake/dbug/malloc/realloc.c' -a X"$1" != X"-c"; then
echo 'x - skipping dmake/dbug/malloc/realloc.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
sed 's/^X//' << 'SHAR_EOF' > 'dmake/dbug/malloc/realloc.c' &&
/*
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 */
#include <stdio.h>
#include "malloc.h"
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 */
#ifndef lint
static
char rcs_hdr[] = "$Id: realloc.c,v 1.8 90/08/29 21:22:52 cpcahil Exp $";
#endif
X
char *
realloc(cptr,size)
X char * cptr;
X unsigned int size;
{
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 void malloc_join();
X void malloc_memset();
X void malloc_split();
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, (int) (ptr->s.size - i));
X
X return(ptr->data);
X
} /* realloc(... */
X
X
/*
X * $Log: realloc.c,v $
X * Revision 1.8 90/08/29 21:22:52 cpcahil
X * miscellaneous lint fixes
X *
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
chmod 0640 dmake/dbug/malloc/realloc.c ||
echo 'restore of dmake/dbug/malloc/realloc.c failed'
Wc_c="`wc -c < 'dmake/dbug/malloc/realloc.c'`"
test 4659 -eq "$Wc_c" ||
echo 'dmake/dbug/malloc/realloc.c: original size 4659, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= dmake/dbug/malloc/string.c ==============
if test -f 'dmake/dbug/malloc/string.c' -a X"$1" != X"-c"; then
echo 'x - skipping dmake/dbug/malloc/string.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
sed 's/^X//' << 'SHAR_EOF' > 'dmake/dbug/malloc/string.c' &&
/*
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>
#include <string.h>
#include <sys/types.h>
#include "malloc.h"
X
#ifndef lint
static
char rcs_hdr[] = "$Id: string.c,v 1.7 90/08/29 22:24:19 cpcahil Exp $";
#endif
X
int malloc_checking = 0;
X
char *
strcat(str1,str2)
X register char * str1;
X register char * str2;
{
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
char *
strdup(str1)
X register char * str1;
{
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
char *
strncat(str1,str2,len)
X register char * str1;
X register char * str2;
X register int len;
{
X int len1;
X int len2;
X char * rtn;
X
X malloc_check_strn("strncat", str2, len);
X
X malloc_checking = 1;
X
X len2 = strlen(str2) + 1;
X len1 = strlen(str1);
X
X malloc_checking = 0;
X
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
int
strcmp(str1,str2)
X register char * str1;
X register char * str2;
{
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
X
X /*
X * in order to deal with the case of a negative last char of either
X * string when the other string has a null
X */
X if( (*str2 == '\0') && (*str1 == '\0') )
X {
X return(0);
X }
X else if( *str2 == '\0' )
X {
X return(1);
X }
X else if( *str1 == '\0' )
X {
X return(-1);
X }
X
X return( *str1 - *str2 );
}
X
int
strncmp(str1,str2,len)
X register char * str1;
X register char * str2;
X register int len;
{
X malloc_check_strn("strncmp", str1, len);
X malloc_check_strn("strncmp", str2, len);
X
X while( --len >= 0 && *str1 && (*str1 == *str2) )
X {
X str1++;
X str2++;
X }
X
X if( len < 0 )
X {
X return(0);
X }
X /*
X * in order to deal with the case of a negative last char of either
X * string when the other string has a null
X */
X if( (*str2 == '\0') && (*str1 == '\0') )
X {
X return(0);
X }
X else if( *str2 == '\0' )
X {
X return(1);
X }
X else if( *str1 == '\0' )
X {
X return(-1);
X }
X
X return( *str1 - *str2 );
}
X
char *
strcpy(str1,str2)
X register char * str1;
X register char * str2;
{
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
char *
strncpy(str1,str2,len)
X register char * str1;
X register char * str2;
X register int len;
{
X extern int malloc_checking;
X char * rtn;
X
X malloc_check_data("strncpy", str1, len);
X malloc_check_strn("strncpy", str2, len);
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
int
strlen(str1)
X register char * str1;
{
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
char *
strchr(str1,c)
X register char * str1;
X register int c;
{
X malloc_check_str("strchr", str1);
X
X while( *str1 && (*str1 != (char) c) )
X {
X str1++;
X }
X
X if(*str1 != (char) c)
X {
X str1 = (char *) 0;
X }
X
X return(str1);
}
X
char *
strrchr(str1,c)
X register char * str1;
X register int c;
{
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 if( *str1 == (char) c)
X {
X rtn = str1;
X }
X
X return(rtn);
}
X
char *
index(str1,c)
X char * str1;
X char c;
{
X return( strchr(str1,c) );
}
X
char *
rindex(str1,c)
X char * str1;
X char c;
{
X return( strrchr(str1,c) );
}
X
char *
strpbrk(str1,str2)
X register char * str1;
X register char * str2;
{
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
int
strspn(str1,str2)
X register char * str1;
X register char * str2;
{
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
int
strcspn(str1,str2)
X register char * str1;
X register char * str2;
{
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 * strtok() source taken from that posted to comp.lang.c by Chris Torek
X * in Jan 1990.
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 * 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 */
char *
strtok(str1, str2)
X char * str1;
X char * str2;
{
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 * 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 */
char *
strtoken(stringp, delim, skip)
X register char **stringp;
X register char *delim;
X int skip;
{
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 * $Log: string.c,v $
X * Revision 1.7 90/08/29 22:24:19 cpcahil
X * added new function to check on strings up to a specified length
X * and used it within several strn* functions.
X *
X * Revision 1.6 90/07/16 20:06:56 cpcahil
X * fixed several minor bugs found with Henry Spencer's string/mem function
X * tester program.
X *
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
chmod 0640 dmake/dbug/malloc/string.c ||
echo 'restore of dmake/dbug/malloc/string.c failed'
Wc_c="`wc -c < 'dmake/dbug/malloc/string.c'`"
test 9382 -eq "$Wc_c" ||
echo 'dmake/dbug/malloc/string.c: original size 9382, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= dmake/dbug/malloc/testmem.c ==============
if test -f 'dmake/dbug/malloc/testmem.c' -a X"$1" != X"-c"; then
echo 'x - skipping dmake/dbug/malloc/testmem.c (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
sed 's/^X//' << 'SHAR_EOF' > 'dmake/dbug/malloc/testmem.c' &&
/*
X * This stuff is all stolen (with permission, since it was in the public
X * domain) from Henry Spencer's string and memory library. Thanks Henry.
X */
X
/*
X * Test program for string(3) routines.
X *
X * Note that at least one Bell Labs implementation of the string
X * routines flunks a couple of these tests -- the ones which test
X * behavior on "negative" characters.
X */
X
#include <stdio.h>
#include <string.h>
X
char * index();
char * rindex();
X
#define STREQ(a, b) (strcmp((a), (b)) == 0)
X
char *it = "<UNSET>"; /* Routine name for message routines. */
int waserror = 0; /* For exit status. */
X
char uctest[] = "\004\203"; /* For testing signedness of chars. */
int charsigned; /* Result. */
X
/*
X - check - complain if condition is not true
X */
void
check(thing, number)
int thing;
int number; /* Test number for error message. */
{
X if (!thing) {
X printf("%s flunked test %d\n", it, number);
X waserror = 1;
X }
}
X
/*
X - equal - complain if first two args don't strcmp as equal
X */
void
equal(a, b, number)
char *a;
char *b;
int number; /* Test number for error message. */
{
X check(a != NULL && b != NULL && STREQ(a, b), number);
}
X
char one[50];
char two[50];
X
#ifdef UNIXERR
#define ERR 1
#endif
#ifdef BERKERR
#define ERR 1
#endif
#ifdef ERR
int f;
extern char *sys_errlist[];
extern int sys_nerr;
extern int errno;
#endif
X
/* ARGSUSED */
main(argc, argv)
int argc;
char *argv[];
{
X /*
X * First, establish whether chars are signed.
X */
X if (uctest[0] < uctest[1])
X charsigned = 0;
X else
X charsigned = 1;
X
X /*
X * Then, do the rest of the work. Split into two functions because
X * some compilers get unhappy about a single immense function.
X */
X first();
X second();
X
X exit((waserror) ? 1 : 0);
}
X
first()
{
X /*
X * Test strcmp first because we use it to test other things.
X */
X it = "strcmp";
X check(strcmp("", "") == 0, 1); /* Trivial case. */
X check(strcmp("a", "a") == 0, 2); /* Identity. */
X check(strcmp("abc", "abc") == 0, 3); /* Multicharacter. */
X check(strcmp("abc", "abcd") < 0, 4); /* Length mismatches. */
X check(strcmp("abcd", "abc") > 0, 5);
X check(strcmp("abcd", "abce") < 0, 6); /* Honest miscompares. */
X check(strcmp("abce", "abcd") > 0, 7);
X check(strcmp("a\203", "a") > 0, 8); /* Tricky if char signed. */
X if (charsigned) /* Sign-bit comparison. */
X check(strcmp("a\203", "a\003") < 0, 9);
X else
X check(strcmp("a\203", "a\003") > 0, 9);
X check(strcmp("a", "a\203") < 0, 10); /* Tricky if char signed. */
X
X /*
X * Test strcpy next because we need it to set up other tests.
X */
X it = "strcpy";
X check(strcpy(one, "abcd") == one, 1); /* Returned value. */
X equal(one, "abcd", 2); /* Basic test. */
X
X (void) strcpy(one, "x");
X equal(one, "x", 3); /* Writeover. */
X equal(one+2, "cd", 4); /* Wrote too much? */
X
X (void) strcpy(two, "hi there");
X (void) strcpy(one, two);
X equal(one, "hi there", 5); /* Basic test encore. */
X equal(two, "hi there", 6); /* Stomped on source? */
X
X (void) strcpy(one, "");
X equal(one, "", 7); /* Boundary condition. */
X
X /*
X * strcat
X */
X it = "strcat";
X (void) strcpy(one, "ijk");
X check(strcat(one, "lmn") == one, 1); /* Returned value. */
X equal(one, "ijklmn", 2); /* Basic test. */
X
X (void) strcpy(one, "x");
X (void) strcat(one, "yz");
X equal(one, "xyz", 3); /* Writeover. */
X equal(one+4, "mn", 4); /* Wrote too much? */
X
X (void) strcpy(one, "gh");
X (void) strcpy(two, "ef");
X (void) strcat(one, two);
X equal(one, "ghef", 5); /* Basic test encore. */
X equal(two, "ef", 6); /* Stomped on source? */
X
X (void) strcpy(one, "");
X (void) strcat(one, "");
X equal(one, "", 7); /* Boundary conditions. */
X (void) strcpy(one, "ab");
X (void) strcat(one, "");
X equal(one, "ab", 8);
X (void) strcpy(one, "");
X (void) strcat(one, "cd");
X equal(one, "cd", 9);
X
X /*
X * strncat - first test it as strcat, with big counts, then
X * test the count mechanism.
X */
X it = "strncat";
X (void) strcpy(one, "ijk");
X check(strncat(one, "lmn", 99) == one, 1); /* Returned value. */
X equal(one, "ijklmn", 2); /* Basic test. */
X
X (void) strcpy(one, "x");
X (void) strncat(one, "yz", 99);
X equal(one, "xyz", 3); /* Writeover. */
X equal(one+4, "mn", 4); /* Wrote too much? */
X
X (void) strcpy(one, "gh");
X (void) strcpy(two, "ef");
X (void) strncat(one, two, 99);
X equal(one, "ghef", 5); /* Basic test encore. */
X equal(two, "ef", 6); /* Stomped on source? */
X
X (void) strcpy(one, "");
X (void) strncat(one, "", 99);
X equal(one, "", 7); /* Boundary conditions. */
X (void) strcpy(one, "ab");
X (void) strncat(one, "", 99);
X equal(one, "ab", 8);
X (void) strcpy(one, "");
X (void) strncat(one, "cd", 99);
X equal(one, "cd", 9);
X
X (void) strcpy(one, "ab");
SHAR_EOF
true || echo 'restore of dmake/dbug/malloc/testmem.c failed'
fi
echo 'End of part 6, continue with part 7'
echo 7 > _shar_seq_.tmp
exit 0
exit 0 # Just in case...
--
Kent Landfield INTERNET: kent at sparky.IMD.Sterling.COM
Sterling Software, IMD UUCP: uunet!sparky!kent
Phone: (402) 291-8300 FAX: (402) 291-4362
Please send comp.sources.misc-related mail to kent at uunet.uu.net.
More information about the Comp.sources.misc
mailing list