dvadura@watdragon.waterloo.edu (Dennis Vadura) (05/11/91)
Submitted-by: Dennis Vadura <dvadura@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@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@uunet.uu.net.