rsalz@bbn.com (Rich Salz) (07/14/90)
Submitted-by: "Conor P. Cahill" <virtech!cpcahil@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@uunet.uu.net. Use a domain-based address or give alternate paths, or you may lose out.