Google
 

Trailing-Edge - PDP-10 Archives - SRI_NIC_PERM_FS_1_19910112 - c/dist/bug-kcc.mail
There are no other files named bug-kcc.mail in the archive.
28-Jul-86 19:25:23-PDT,25272;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 28 Jul 86 19:25:03-PDT
Date: Mon 28 Jul 86 20:25:15-MDT
From: Frank J. Wancho <[email protected]>
Subject: New error messages
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

I know I'm jumping the gun, but...

The following error and warning messages were produced by CC(512)
which were not (caught?) by CC(480).  Offending source file follows.

--Frank
--------------------

KCC:	ARCLZW

Warning at line 92 of ARCLZW.C:
static long *htab = strtab;	
Implicit conversion - pointer to pointer

Error at line 92 of ARCLZW.C:
static long *htab = strtab;	
Pointer initializer not constant

Error at line 92 of ARCLZW.C:
static long *htab = strtab;	
Null initializer for "htab"

Warning at line 96 of ARCLZW.C:
static unsigned char *suffix = strtab; 
Implicit conversion - pointer to pointer

Error at line 96 of ARCLZW.C:
static unsigned char *suffix = strtab; 
Pointer initializer not constant

Error at line 96 of ARCLZW.C:
static unsigned char *suffix = strtab; 
Null initializer for "suffix"
?4 error(s) detected

--------------------ARCLZW.C--------------------
/*  ARC - Archive utility - ARCLZW

#define TAG $$segment(@1,$$index(@1,=)+1)
#define VERSION Version TAG(
TED_VERSION DB =1.88), created on TAG(
TED_DATE DB =01/20/86) at TAG(
TED_TIME DB =16:47:04)
#undefine TAG
    VERSION

(C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED

    By:  Thom Henderson

    Description:
	 This file contains the routines used to implement Lempel-Zev
	 data compression, which calls for building a coding table on
	 the fly.  This form of compression is especially good for encoding
	 files which contain repeated strings, and can often give dramatic
	 improvements over traditional Huffman SQueezing.

    Language:
	 Computer Innovations Optimizing C86

    Programming notes:
	 In this section I am drawing heavily on the COMPRESS program
	 from UNIX.  The basic method is taken from "A Technique for High
	 Performance Data Compression", Terry A. Welch, IEEE Computer
	 Vol 17, No 6 (June 1984), pp 8-19.  Also see "Knuth's Fundamental
	 Algorithms", Donald Knuth, Vol 3, Section 6.4.

	 As best as I can tell, this method works by tracing down a hash
	 table of code strings where each entry has the property:

	      if <string> <char> is in the table
	      then <string> is in the table.
*/
#include <stdio.h>
#include "arc.h"

/* definitions for older style crunching */

#define FALSE	 0
#define TRUE	 !FALSE
#define TABSIZE  4096
#define NO_PRED  0xFFFF
#define EMPTY	 0xFFFF
#define NOT_FND  0xFFFF

static unsigned int inbuf;	       /* partial input code storage */
static int sp;			       /* current stack pointer */

static struct entry		       /* string table entry format */
{   char used;			       /* true when this entry is in use */
    unsigned int next;		       /* ptr to next in collision list */
    unsigned int predecessor;	       /* code for preceeding string */
    unsigned char follower;	       /* char following string */
}   strtab[TABSIZE];		   /* the code string table */


/* definitions for the new dynamic Lempel-Zev crunching */

#define BITS   12		       /* maximum bits per code */
#define HSIZE  5003		       /* 80% occupancy */
#define INIT_BITS 9		       /* initial number of bits/code */

static int n_bits;		       /* number of bits/code */
static int maxcode;		       /* maximum code, given n_bits */
#define MAXCODE(n)	((1<<(n)) - 1) /* maximum code calculation */
static int codemax =  1 << BITS;    /* largest possible code (+1) */

static char buf[BITS];		       /* input/output buffer */

static unsigned char lmask[9] =        /* left side masks */
{   0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00 };
static unsigned char rmask[9] =        /* right side masks */
{   0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};

static int offset;		       /* byte offset for code output */
static long in_count;		       /* length of input */
static long bytes_out;		       /* length of compressed output */
static unsigned int ent;

/* To save much memory (which we badly need at this point), we overlay
 * the table used by the previous version of Lempel-Zev with those used
 * by the new version.  Since no two of these routines will be used
 * together, we can safely do this.  Note that the tables used for Huffman
 * squeezing may NOT overlay these, since squeezing and crunching are done
 * in parallel.
 */

static long *htab = strtab;	   /* hash code table	(crunch) */
static unsigned int codetab[HSIZE];    /* string code table (crunch) */

static unsigned int *prefix = codetab; /* prefix code table (uncrunch) */
static unsigned char *suffix = strtab;  /* suffix table (uncrunch) */

static int free_ent;		       /* first unused entry */
static int frstcmp;		      /* true at start of compression */
static unsigned char stack[HSIZE];     /* local push/pop stack */

/*
 * block compression parameters -- after all codes are used up,
 * and compression rate changes, start over.
 */

static int clear_flg;
static long ratio;
#define CHECK_GAP 10000		       /* ratio check interval */
static long checkpoint;

/*
 * the next two codes should not be changed lightly, as they must not
 * lie within the contiguous general code space.
 */
#define FIRST	257		       /* first free entry */
#define CLEAR	256		       /* table clear output code */

static cl_block(t)		       /* table clear for block compress */
FILE *t;			       /* our output file */
{
    long int rat;

    checkpoint = in_count + CHECK_GAP;

    if(in_count > 0x007fffff)	       /* shift will overflow */
    {	 rat = bytes_out >> 8;
	 if(rat == 0)		       /* Don't divide by zero */
	      rat = 0x7fffffff;
	 else rat = in_count / rat;
    }
    else rat = (in_count<<8)/bytes_out;/* 8 fractional bits */

    if(rat > ratio)
	 ratio = rat;
    else
    {	 ratio = 0;
	 setmem(htab,HSIZE*sizeof(long),0xff);
	 free_ent = FIRST;
	 clear_flg = 1;
	 putcode(CLEAR,t);
    }
}

/*****************************************************************
 *
 * Output a given code.
 * Inputs:
 *	code:	A n_bits-bit integer.  If == -1, then EOF.  This assumes
 *		that n_bits =< (long)wordsize - 1.
 * Outputs:
 *	Outputs code to the file.
 * Assumptions:
 *	Chars are 8 bits long.
 * Algorithm:
 *	Maintain a BITS character long buffer (so that 8 codes will
 * fit in it exactly).  When the buffer fills up empty it and start over.
 */

static putcode(code,t)		       /* output a code */
int code;			       /* code to output */
FILE *t;			       /* where to put it */
{
    int r_off = offset;		       /* right offset */
    int bits = n_bits;		       /* bits to go */
    char *bp = buf;		       /* buffer pointer */
    int n;			       /* index */

    if(code >= 0)		       /* if a real code */
    {	 /*
	  * Get to the first byte.
	  */
	 bp += (r_off >> 3);
	 r_off &= 7;

	 /*
	  * Since code is always >= 8 bits, only need to mask the first
	  * hunk on the left.
	  */
	 *bp = (*bp&rmask[r_off]) | (code<<r_off) & lmask[r_off];
	 bp++;
	 bits -= (8 - r_off);
	 code >>= (8 - r_off);

	 /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
	 if(bits >= 8)
	 {    *bp++ = code;
	      code >>= 8;
	      bits -= 8;
	 }

	 /* Last bits. */
	 if(bits)
	      *bp = code;

	 offset += n_bits;

	 if(offset == (n_bits << 3))
	 {    bp = buf;
	      bits = n_bits;
	      bytes_out += bits;
	      do
		   putpak(*bp++,t);
	      while(--bits);
	      offset = 0;
	 }

	 /*
	  * If the next entry is going to be too big for the code size,
	  * then increase it, if possible.
	  */
	 if(free_ent>maxcode || clear_flg>0)
	 {    /*
	       * Write the whole buffer, because the input side won't
	       * discover the size increase until after it has read it.
	       */
	      if(offset > 0)
	      {    bp = buf;	       /* reset pointer for writing */
		   bytes_out += n = n_bits;
		   while(n--)
			putpak(*bp++,t);
	      }
	      offset = 0;

	      if(clear_flg)	       /* reset if clearing */
	      {    maxcode = MAXCODE(n_bits = INIT_BITS);
		   clear_flg = 0;
	      }
	      else		       /* else use more bits */
	      {    n_bits++;
		   if(n_bits == BITS)
			maxcode = codemax;
		   else
			maxcode = MAXCODE(n_bits);
	      }
	 }
    }

    else			       /* dump the buffer on EOF */
    {	 bytes_out += n = (offset+7) / 8;

	 if(offset > 0)
	      while(n--)
		   putpak(*bp++,t);
	 offset = 0;
    }
}

/*****************************************************************
 *
 * Read one code from the standard input.  If EOF, return -1.
 * Inputs:
 *	cmpin
 * Outputs:
 *	code or -1 is returned.
 */

static int getcode(f)		       /* get a code */
FILE *f;			       /* file to get from */
{
    int code;
    static int offset = 0, size = 0;
    int r_off, bits;
    unsigned char *bp = buf;

    if(clear_flg > 0 || offset >= size || free_ent > maxcode)
    {	 /*
	  * If the next entry will be too big for the current code
	  * size, then we must increase the size.  This implies reading
	  * a new buffer full, too.
	  */
	 if(free_ent > maxcode)
	 {    n_bits++;
	      if(n_bits == BITS)
		   maxcode = codemax;	 /* won't get any bigger now */
	      else maxcode = MAXCODE(n_bits);
	 }
	 if(clear_flg > 0)
	 {    maxcode = MAXCODE(n_bits = INIT_BITS);
	      clear_flg = 0;
	 }

	 for(size=0; size<n_bits; size++)
	 {    if((code=getunp(f))==EOF)
		   break;
	      else buf[size] = code;
	 }
	 if(size <= 0)
	      return -1;	       /* end of file */

	 offset = 0;
	 /* Round size down to integral number of codes */
	 size = (size << 3)-(n_bits - 1);
    }
    r_off = offset;
    bits = n_bits;

    /*
     * Get to the first byte.
     */
    bp +=(r_off >> 3);
    r_off &= 7;

    /* Get first part (low order bits) */
    code = (*bp++ >> r_off);
    bits -= 8 - r_off;
    r_off = 8 - r_off;		       /* now, offset into code word */

    /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
    if(bits >= 8)
    {	 code |= *bp++ << r_off;
	 r_off += 8;
	 bits -= 8;
    }
    /* high order bits. */
    code |= (*bp & rmask[bits]) << r_off;
    offset += n_bits;

    return code;
}

/*
 * compress a file
 *
 * Algorithm:  use open addressing double hashing (no chaining) on the
 * prefix code / next character combination.  We do a variant of Knuth's
 * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
 * secondary probe.  Here, the modular division first probe is gives way
 * to a faster exclusive-or manipulation.  Also do block compression with
 * an adaptive reset, where the code table is cleared when the compression
 * ratio decreases, but after the table fills.  The variable-length output
 * codes are re-sized at this point, and a special CLEAR code is generated
 * for the decompressor.
 */

initcm(f,t)			      /* initialize for compression */
FILE *f;			       /* file we will be compressing */
FILE *t;			       /* where we will put it */
{
    offset = 0;
    bytes_out = 1;
    clear_flg = 0;
    ratio = 0;
    in_count = 1;
    checkpoint = CHECK_GAP;
    maxcode = MAXCODE(n_bits = INIT_BITS);
    free_ent = FIRST;
    setmem(htab,HSIZE*sizeof(long),0xff);
    n_bits = INIT_BITS;		       /* set starting code size */

    putpak(BITS,t);		     /* note our max code length */

    frstcmp = 1;		      /* next byte will be first */
}

putcm(c,t)			     /* compress a character */
unsigned char c;		       /* character to compress */
FILE *t;			       /* where to put it */
{
    static long fcode;
    static int hshift;
    int i;
    int disp;

    if(frstcmp)			      /* special case for first byte */
    {	 ent = c;		       /* remember first byte */

	 hshift = 0;
	 for(fcode=(long)HSIZE;  fcode<65536L; fcode*=2L)
	      hshift++;
	 hshift = 8 - hshift;	       /* set hash code range bound */

	 frstcmp = 0;		      /* no longer first */
	 return;
    }

    in_count++;
    fcode =(long)(((long)c << BITS)+ent);
    i = (c<<hshift)^ent;	       /* xor hashing */

    if(htab[i]==fcode)
    {	 ent = codetab[i];
	 return;
    }
    else if(htab[i]<0)		       /* empty slot */
	 goto nomatch;
    disp = HSIZE - i;		       /* secondary hash (after G.Knott) */
    if(i == 0)
	 disp = 1;

probe:
    if((i -= disp) < 0)
	 i += HSIZE;

    if(htab[i] == fcode)
    {	 ent = codetab[i];
	 return;
    }
    if(htab[i] > 0)
	 goto probe;

nomatch:
    putcode(ent,t);
    ent = c;
    if(free_ent < codemax)
    {	 codetab[i] = free_ent++;      /* code -> hashtable */
	 htab[i] = fcode;
    }
    else if((long int)in_count >= checkpoint)
	 cl_block(t);
}

long pred_cm(t)			       /* finish compressing a file */
FILE *t;			       /* where to put it */
{
    putcode(ent,t);		       /* put out the final code */
    putcode(-1,t);		       /* tell output we are done */

    return bytes_out;		       /* say how big it got */
}

/*
 * Decompress a file.  This routine adapts to the codes in the file
 * building the string table on-the-fly; requiring no table to be stored
 * in the compressed file.  The tables used herein are shared with those of
 * the compress() routine.  See the definitions above.
 */

decomp(f,t)			       /* decompress a file */
FILE *f;			       /* file to read codes from */
FILE *t;			       /* file to write text to */
{
    unsigned char *stackp;
    int finchar;
    int code, oldcode, incode;

    if((code=getunp(f))!=BITS)
    {	 printf("File packed with %d bits, I can only handle %d",code,BITS);
	 exit(1);
    }

    n_bits = INIT_BITS;		       /* set starting code size */
    clear_flg = 0;

    /*
     * As above, initialize the first 256 entries in the table.
     */
    maxcode = MAXCODE(n_bits=INIT_BITS);
    for(code = 255; code >= 0; code--)
    {	 prefix[code] = 0;
	 suffix[code] = (unsigned char)code;
    }
    free_ent = FIRST;

    finchar = oldcode = getcode(f);
    if(oldcode == -1)		       /* EOF already? */
	 return;		       /* Get out of here */
    putncr((char)finchar,t);	     /* first code must be 8 bits=char */
    stackp = stack;

    while((code = getcode(f))> -1)
    {	 if(code==CLEAR)
	 {    for(code = 255; code >= 0; code--)
		   prefix[code] = 0;
	      clear_flg = 1;
	      free_ent = FIRST - 1;
	      if((code=getcode(f))==-1)/* O, untimely death! */
		   break;
	 }
	 incode = code;
	 /*
	  * Special case for KwKwK string.
	  */
	 if(code >= free_ent)
	 {    *stackp++ = finchar;
	      code = oldcode;
	 }

	 /*
	  * Generate output characters in reverse order
	  */
	 while(code >= 256)
	 {    *stackp++ = suffix[code];
	      code = prefix[code];
	 }
	 *stackp++ = finchar = suffix[code];

	 /*
	  * And put them out in forward order
	  */
	 do
	      putncr(*--stackp,t);
	 while(stackp > stack);

	 /*
	  * Generate the new entry.
	  */
	 if((code=free_ent) < codemax)
	 {    prefix[code] = (unsigned short)oldcode;
	      suffix[code] = finchar;
	      free_ent = code+1;
	 }
	 /*
	  * Remember previous code.
	  */
	 oldcode = incode;
    }
}


/*************************************************************************
 * Please note how much trouble it can be to maintain upwards		 *
 * compatibility.  All that follows is for the sole purpose of unpacking *
 * files which were packed using an older method.			 *
 *************************************************************************/


/*  The h() pointer points to the routine to use for calculating a hash
    value.  It is set in the init routines to point to either of oldh()
    or newh().

    oldh() calculates a hash value by taking the middle twelve bits
    of the square of the key.

    newh() works somewhat differently, and was tried because it makes
    ARC about 23% faster.  This approach was abandoned because dynamic
    Lempel-Zev (above) works as well, and packs smaller also.  However,
    inadvertent release of a developmental copy forces us to leave this in.
*/

static unsigned (*h)();		       /* pointer to hash function */

static unsigned oldh(pred,foll)        /* old hash function */
unsigned int pred;		       /* code for preceeding string */
unsigned char foll;		       /* value of following char */
{
    long local;			       /* local hash value */

    local = (pred + foll) | 0x0800;    /* create the hash key */
    local *= local;		       /* square it */
    return (local >> 6) & 0x0FFF;      /* return the middle 12 bits */
}

static unsigned newh(pred,foll)        /* new hash function */
unsigned int pred;		       /* code for preceeding string */
unsigned char foll;		       /* value of following char */
{
    return ((pred+foll)*15073)&0xFFF;  /* faster hash */
}

/*  The eolist() function is used to trace down a list of entries with
    duplicate keys until the last duplicate is found.
*/

static unsigned eolist(index)	       /* find last duplicate */
unsigned int index;
{
    int temp;

    while(temp=strtab[index].next) /* while more duplicates */
	 index = temp;

    return index;
}

/*  The hash() routine is used to find a spot in the hash table for a new
    entry.  It performs a "hash and linear probe" lookup, using h() to
    calculate the starting hash value and eolist() to perform the linear
    probe.  This routine DOES NOT detect a table full condition.  That
    MUST be checked for elsewhere.
*/

static unsigned hash(pred,foll)        /* find spot in the string table */
unsigned int pred;		       /* code for preceeding string */
unsigned char foll;		       /* char following string */
{
    unsigned int local, tempnext;      /* scratch storage */
    struct entry *ep;		       /* allows faster table handling */

    local = (*h)(pred,foll);	       /* get initial hash value */

    if(!strtab[local].used)	   /* if that spot is free */
	 return local;		       /* then that's all we need */

    else			       /* else a collision has occured */
    {	 local = eolist(local);        /* move to last duplicate */

	 /*   We must find an empty spot. We start looking 101 places
	      down the table from the last duplicate.
	 */

	 tempnext = (local+101) & 0x0FFF;
	 ep = &strtab[tempnext];   /* initialize pointer */

	 while(ep->used)	       /* while empty spot not found */
	 {    if(++tempnext==TABSIZE)  /* if we are at the end */
	      {    tempnext = 0;       /* wrap to beginning of table*/
		   ep = strtab;
	      }
	      else ++ep;	       /* point to next element in table */
	 }

	 /*   local still has the pointer to the last duplicate, while
	      tempnext has the pointer to the spot we found.  We use
	      this to maintain the chain of pointers to duplicates.
	 */

	 strtab[local].next = tempnext;

	 return tempnext;
    }
}

/*  The unhash() function is used to search the hash table for a given key.
    Like hash(), it performs a hash and linear probe search.  It returns
    either the number of the entry (if found) or NOT_FND (if not found).
*/

static unsigned unhash(pred,foll)      /* search string table for a key */
unsigned int pred;		       /* code of preceeding string */
unsigned char foll;		       /* character following string */
{
    unsigned int local, offset;        /* scratch storage */
    struct entry *ep;		       /* this speeds up access */

    local = (*h)(pred,foll);	       /* initial hash */

    while(1)
    {	 ep = &strtab[local];	   /* speed up table access */

	 if((ep->predecessor==pred) && (ep->follower==foll))
	      return local;	       /* we have a match */

	 if(!ep->next)		       /* if no more duplicates */
	      return NOT_FND;	       /* then key is not listed */

	 local = ep->next;	       /* move on to next duplicate */
    }
}

/*  The inittab() routine is used to initialize our hash table.
    You realize, of course, that "initialize" is a complete misnomer.
*/

static inittab()		      /* set ground state in hash table */
{
    unsigned int i;		       /* table index */

    setmem((char *)strtab,sizeof(strtab),0);

    for(i=0; i<256; i++)	       /* list all single byte strings */
	 upd_tab(NO_PRED,i);

    inbuf = EMPTY;		       /* nothing is in our buffer */
}

/*  The upd_tab routine is used to add a new entry to the string table.
    As previously stated, no checks are made to ensure that the table
    has any room.  This must be done elsewhere.
*/

upd_tab(pred,foll)		       /* add an entry to the table */
unsigned int pred;		       /* code for preceeding string */
unsigned int foll;		       /* character which follows string */
{
    struct entry *ep;		       /* pointer to current entry */

    /* calculate offset just once */

    ep = &strtab[hash(pred,foll)];

    ep->used = TRUE;		       /* this spot is now in use */
    ep->next = 0;		       /* no duplicates after this yet */
    ep->predecessor = pred;	       /* note code of preceeding string */
    ep->follower = foll;	       /* note char after string */
}

/*  This algorithm encoded a file into twelve bit strings (three nybbles).
    The gocode() routine is used to read these strings a byte (or two)
    at a time.
*/

static gocode(fd)		       /* read in a twelve bit code */
FILE *fd;			       /* file to get code from */
{
    unsigned int localbuf, returnval;

    if(inbuf==EMPTY)		       /* if on a code boundary */
    {	 if((localbuf=getunp(fd))==EOF)   /* get start of next code */
	      return EOF;	       /* pass back end of file status */
	 localbuf &= 0xFF;	       /* mask down to true byte value */
	 if((inbuf=getunp(fd))==EOF) /* get end of code, start of next */
	      return EOF;	       /* this should never happen */
	 inbuf &= 0xFF;		       /* mask down to true byte value */

	 returnval = ((localbuf<<4)&0xFF0) + ((inbuf>>4)&0x00F);
	 inbuf &= 0x000F;	       /* leave partial code pending */
    }

    else			       /* buffer contains first nybble */
    {	 if((localbuf=getunp(fd))==EOF)
	      return EOF;
	 localbuf &= 0xFF;

	 returnval = localbuf + ((inbuf<<8)&0xF00);
	 inbuf = EMPTY;		       /* note no hanging nybbles */
    }
    return returnval;		       /* pass back assembled code */
}

static push(c)			       /* push char onto stack */
int c;				       /* character to push */
{
    stack[sp] = ((char) c);	       /* coerce integer into a char */

    if(++sp >= TABSIZE)
    {	 printf("Stack overflow\n");
	 exit(1);
    }
}

static int pop()		       /* pop character from stack */
{
    if(sp>0)
	 return ((int) stack[--sp]);   /* leave ptr at next empty slot */

    else return EMPTY;
}

/***** LEMPEL-ZEV DECOMPRESSION *****/

static int codcnt;		   /* needed to detect table full */
static unsigned code;		       /* where we are so far */
static int firstc;		       /* true only on first character */

initucr(new)			      /* get set for uncrunching */
int new;			       /* true to use new hash function */
{
    if(new)			       /* set proper hash function */
	 h = newh;
    else h = oldh;

    sp = 0;			       /* clear out the stack */
    inittab();			      /* set up atomic code definitions */
    codcnt = TABSIZE - 256;	   /* note space left in table */
    firstc = 1;			       /* true only on first code */
}

int getucr(f)			     /* get next uncrunched byte */
FILE *f;			       /* file containing crunched data */
{
    unsigned int c;		       /* a character of input */
    int code, newcode;
    static int oldcode, finchar;
    struct entry *ep;		       /* allows faster table handling */

    if(firstc)			       /* first code is always known */
    {	 firstc = FALSE;	       /* but next will not be first */
	 oldcode = gocode(f);
	 return finchar = strtab[oldcode].follower;
    }

    if(!sp)			       /* if stack is empty */
    {	 if((code=newcode=gocode(f))==EOF)
	      return EOF;

	 ep = &strtab[code];	   /* initialize pointer */

	 if(!ep->used)		       /* if code isn't known */
	 {    code = oldcode;
	      ep = &strtab[code];  /* re-initialize pointer */
	      push(finchar);
	 }

	 while(ep->predecessor!=NO_PRED)
	 {    push(ep->follower);      /* decode string backwards */
	      code = ep->predecessor;
	      ep = &strtab[code];
	 }

	 push(finchar=ep->follower);   /* save first character also */

	 /*   The above loop will terminate, one way or another,
	      with strtab[code].follower equal to the first
	      character in the string.
	 */

	 if(codcnt)		   /* if room left in string table */
	 {    upd_tab(oldcode,finchar);
	      --codcnt;
	 }

	 oldcode = newcode;
    }

    return pop();		       /* return saved character */
}
====================
-------
29-Jul-86 10:47:58-PDT,2272;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Tue 29 Jul 86 10:47:50-PDT
Date: Tue, 29 Jul 1986  11:47 MDT
Message-ID: <[email protected]>
From: [email protected]
To:   [email protected]
cc:   [email protected]
Subject: File-level compatibility

There is probably a better subject line.  Let me explain:

The program I'm trying to port was developed on and for MSDOS.  We
store files created by this program as TOPS-20 8-bit binary files, and
we would like the capability to manipulate those files or even create
them.  The catch is that 8-bit file I/O data conversion is apparently
not compatible, and I'm looking for a way around the problem.

For example, these files contain header information consisting of
entries containing a ^Z followed by a one byte version number and data
of the form below.  The last entry flag is a ^Z followed by a NULL
byte.  The first two bytes of each entry are read by fgetc - no
problem.  However, the remaining data is read by an fread, and that's
where there is the basic incompatibility.  I'm open to suggestions.

The following are the pertinent code fragments:

struct heads                           /* archive entry header format */
{   char name[100];			/* file name */
    long size;                         /* size of file, in bytes */
    unsigned int date;                 /* creation date */
    unsigned int time;                 /* creation time */
    int crc;                           /* cyclic redundancy check */
    long length;                       /* true file length */
}   ;

struct heads *hdr;		       /* storage for header */
FILE *f;			       /* archive to read header from */

    fread(hdr,sizeof(struct heads),1,f);

sizeof(struct heads) is 36...  The problem is the same with fwrite.
Right now, I'm fooling with an interim "solution", and that is to read
and write each piece of data in the structure according to type.  But,
in the long run, this isn't a very generic/portable way to handle such
cases.  Perhaps we need some sort of compatibility interface for the
case of 8-bit binary I/O that converts the KCC concept of data storage
to/from the 8-bit binary world...

--Frank
29-Jul-86 11:19:27-PDT,1197;000000000001
Mail-From: KLH created at 29-Jul-86 11:19:21
Date: Tue 29 Jul 86 11:19:21-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: File-level compatibility
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

fread and fwrite are specifically documented to be non-portable.  Any code
that uses those routines is probably not going to work on another machine.
8-bit-ness has nothing to do with it; remember that different machines
have different byte ordering and you can even have a different size for
int and long on the same machine, depending on what compiler you are using.
This is why TAR format writes out its numbers as ASCII strings rather than
as 8-bit binary bytes which have to be concatenated and possibly sign-extended
in an unpredictable manner.

Transporting a program will probably work.  Transporting the data files
produced by that program probably will not work unless the files are stream
oriented.  If you want to be able to transport a binary data file, be
prepared to write a conversion program.  That's about the size of it.
-------
29-Jul-86 17:12:34-PDT,519;000000000001
Mail-From: KLH created at 29-Jul-86 17:12:30
Date: Tue 29 Jul 86 17:12:30-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: New error messages
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

New KCC (513) will complain (an explicit cast is required) but proceed.
Not all compilers will accomodate constant-expression casts however,
especially when an address is involved.
-------
30-Jul-86 00:32:20-PDT,564;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Wed 30 Jul 86 00:31:43-PDT
Date: Tue 29 Jul 86 23:05:42-MDT
From: Frank J. Wancho <[email protected]>
Subject: Problem with fseek
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

Given a file opened with "rR8", followed by several fgetc calls,
fseek(f,offset,1) has garbage in AC2 for the SFPTR and does not
appear to call RFPTR to find the current position to which to
add the offset.

--Frank
-------
30-Jul-86 01:02:12-PDT,451;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Wed 30 Jul 86 01:02:03-PDT
Date: Tue 29 Jul 86 19:24:10-MDT
From: Frank J. Wancho <[email protected]>
Subject: OPENF and OF%PLN
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

Please set OF%PLN on the OPENF% when the fopen request is R8
so that fseek works properly.

Thanks,
Frank
-------
30-Jul-86 15:21:23-PDT,413;000000000001
Mail-From: IAN created at 30-Jul-86 15:21:21
Date: Wed 30 Jul 86 15:21:21-PDT
From: Ian Macky <[email protected]>
Subject: Re: OPENF and OF%PLN
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

OK, OF%PLN will be set in the future.  From your message, I gather this
fixes your problem with fseek?
-------
30-Jul-86 19:48:22-PDT,747;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Wed 30 Jul 86 19:48:17-PDT
Date: Wed 30 Jul 86 20:15:09-MDT
From: Frank J. Wancho <[email protected]>
Subject: Re: OPENF and OF%PLN
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Ian,

The OF%PLN addition will only help fseek not skip over nulls, etc.
There is still a problem with fseek because I patched the .EXE
file to make OPENF have the OF%PLN bit set and it made no difference.
fseek was still not calling RFPTR and the offset given to SFPTR was
wrong: with values of 1001, 2002, 3003, etc.

--Frank
-------
31-Jul-86 21:20:38-PDT,1529;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Thu 31 Jul 86 21:20:22-PDT
Date: Thu 31 Jul 86 22:20:09-MDT
From: Frank J. Wancho <[email protected]>
Subject: One-pass libraries, fseek(), and fopen(f,"wR8")
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

Ken, Ian, etal,

As it appears that LINK tries to resolve external references in one
pass of search libraries, it may interest you to check out a FORTRAN
program written by Neil Maron and last handled by Norm Samuelson
called LIBORD.  I only recently got it working to process my library
file.  Unfortunately, there is no associated doc file with the program
to give you clues as to what to do with the output of this program.
You are welcome to my copy of the source, provided you let me know
what you make of its output.  It would probably be a good candidate
for conversion to C...  See [SIMTEL20]SS:<SOURCES.UNSUPPORTED>LIBORD.*.

I finally had to cheat to make an fseek-like function of my own that
simply repositions the file pointer by the requested offset by the
appropriate number of fgetc's, a rather inefficient workaround.  If
the option is other than 1, the args are passed on to the regular
fseek.  My other thought was that perhaps the buffered input was
getting in the way.  I inserted a setbuf(arc,NULL); to no avail.

Now, my most recent discovery is that fopen(f,"wR8") opens the file in
7-bit mode anyway!

--Frank
-------
 2-Aug-86 02:24:32-PDT,624;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sat 2 Aug 86 02:24:20-PDT
Date: Sat 2 Aug 86 03:24:13-MDT
From: Frank J. Wancho <[email protected]>
Subject: 8-bit fopen
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

The mystery is solved!  The documentation does not match
the current implementation: "Following the (optional)..."
should read, "Preceding the (optional) raw-mode flag..."

In other words, fopen(f,"w8R") works correctly, while
fopen(f,"wR8") opens the file in 7-bit mode...

--Frank
-------
 2-Aug-86 20:14:44-PDT,762;000000000001
Mail-From: IAN created at  2-Aug-86 20:14:32
Date: Sat 2 Aug 86 20:14:32-PDT
From: Ian Macky <[email protected]>
Subject: Re: 8-bit fopen
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

you're right, the documentation was in error.  one of the changes i'm
in the middle of making is to allow the flags to fopen in any order,
so this won't be an issue again, with the change that instead of 'R'
for "Raw mode", the name is being changed to 'C' for "Converted"
(since "raw" already had meaning within unix); to force unconverted,
the syntax is "C-", which will be the syntax for any additional flags
we may add, to turn them off...

--ian
-------
 2-Aug-86 20:21:35-PDT,488;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sat 2 Aug 86 20:21:17-PDT
Date: Sat 2 Aug 86 21:21:13-MDT
From: Frank J. Wancho <[email protected]>
Subject: Re: 8-bit fopen
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Ian,

I gather fixing fseek is a "bigger" problem, or is it a problem?

--Frank
-------
 3-Aug-86 21:49:57-PDT,1056;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sun 3 Aug 86 21:49:53-PDT
Date: Sun 3 Aug 86 22:49:52-MDT
From: Frank J. Wancho <[email protected]>
Subject: malloc(), realloc(), and free()
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

All three subject functions seem to have problems of
one sort or another.  When malloc() appears to work,
then its corresponding free() complains about an invalid
block.  (This also happened with CC itself when there were
an excessive number of errors.  I no longer have the
source file which demonstrated that problem.)  realloc()
likewise complains about an invalid block, even when
called just once.  In most cases, I just ripped out the
mallocs and frees and made the variables static.  The
remaining realloc doesn't afford me that luxury.

One other query:  what can I set so that a wildcard given
on the command line to my resulting executable doesn't
return "?No match"?

--Frank
-------
 3-Aug-86 23:15:01-PDT,664;000000000001
Mail-From: KLH created at  3-Aug-86 23:14:57
Date: Sun 3 Aug 86 23:14:57-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: malloc(), realloc(), and free()
To: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Many programs here (including KCC itself) use malloc/free.  You'll
have to furnish a small program that demonstrates the error.  I suspect
that the program is neglecting to declare malloc as "char *malloc()",
or is giving free() a pointer which is not of (char *) type.
CC.DOC specifically mentions this as a common cause of problems.
-------
 4-Aug-86 12:32:47-PDT,2711;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 4 Aug 86 12:32:38-PDT
Date: Mon 4 Aug 86 13:32:27-MDT
From: Frank J. Wancho <[email protected]>
Subject: realloc() code fragment
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

Ken,

It's difficult to extract portions of a rather large and complex
package to build it into a standalone demo of a problem.  It is not
clear that the extraction process itself would be blameless.  Instead,
what I present below are the pertinent pieces which cause the
"realloc(): tried to reallocate invalid block" error message.  Maybe
there's something obvious...

--Frank
--------------------
addarc (num, arg, move, update, fresh)/* add files to archive */
int     num;			/* number of arguments */
char   *arg[];			/* pointers to arguments */
int     move;			/* true if moving file */
int     update;			/* true if updating */
int     fresh;			/* true if freshening */
{
    char   *d, *dir ();		/* directory junk */
    char    buf[STRLEN];	/* pathname buffer */
    char   **path;		/* pointer to pointers to paths */
    char   **name;		/* pointer to pointers to names */
    int     nfiles = 0;		/* number of files in lists */
    int     notemp;		/* true until a template works */
    int     nowork = 1;		/* true until files are added */
    char   *i, *rindex ();	/* string indexing junk */
    char   *malloc (), *realloc ();/* memory allocators */
    int     m, n;		/* indices */

    if (num < 1) {		/* if no files named */
	num = 1;		/* then fake one */
	arg[0] = "*.*";		/* add everything */
    }

    for (n = 0; n < num; n++) {	/* for each template supplied */
	strcpy (buf, arg[n]);	/* get ready to fix path */
	if (!(i = rindex (buf, '\\')))
	    if (!(i = rindex (buf, '/')))
		if (!(i = rindex (buf, ':')))
		    i = buf - 1;
	i++;			/* pointer to where name goes */

	notemp = 1;		/* reset files flag */
	for (d = dir (arg[n], 0); *d; d = dir (NULL, 0)) {
	    notemp = 0;		/* template is giving results */
	    nfiles++;		/* add each matching file */
	    path = (char **) realloc (path, nfiles * sizeof (char **));
	    name = (char **) realloc (name, nfiles * sizeof (char **));
	    strcpy (i, d);	/* put name in path */
	    path[nfiles - 1] = malloc (strlen (buf) + 1);
	    strcpy (path[nfiles - 1], buf);
	    name[nfiles - 1] = d;/* save name */
	}
	if (notemp && warn)
	    printf ("No files match: %s\n", arg[n]);
    }

There's more, but this should be sufficient.  The error occurs on the
first realloc above in the first iteration of the loop.
====================
-------
 5-Aug-86 00:27:17-PDT,521;000000000001
Mail-From: KLH created at  5-Aug-86 00:27:12
Date: Tue 5 Aug 86 00:27:12-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: realloc() code fragment
To: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Yes, there is an obvious bug in that example.  Namely, on the first
pass, "path" has not been initialized to anything.  Its contents will
be garbage, and realloc() is justified in complaining about it.
-------
 5-Aug-86 12:25:13-PDT,493;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Tue 5 Aug 86 12:25:09-PDT
Date: Tue 5 Aug 86 13:24:24-MDT
From: Frank J. Wancho <[email protected]>
Subject: Major LSEEK bug!
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

On the assumption I found the current version of LSEEK.C,
the bug is that all settings of arg_block[2] reference
whence instead of offset!!!

--Frank
-------
 5-Aug-86 16:32:22-PDT,475;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Tue 5 Aug 86 16:32:14-PDT
Date: Tue 5 Aug 86 17:31:51-MDT
From: Frank J. Wancho <[email protected]>
Subject: Minor printf bug (%04X)
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

%04X (uppercase X) uppercases only the last digit in the string
instead of the whole string.  (abcD instead of ABCD)

--Frank
-------
 5-Aug-86 16:42:48-PDT,322;000000000001
Mail-From: IAN created at  5-Aug-86 16:42:24
Date: Tue 5 Aug 86 16:42:24-PDT
From: Ian Macky <[email protected]>
Subject: Re: Minor printf bug (%04X)
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Fixed.
-------
 6-Aug-86 10:11:57-PDT,656;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Wed 6 Aug 86 10:11:52-PDT
Date: Wed 6 Aug 86 11:11:13-MDT
From: Frank J. Wancho <[email protected]>
Subject: printf philosophical question
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

It seems that printf output is buffered until a "\n" is seen.
Is this "standard" behavior?  What I find myself doing is
adding fflush(stdout) lines after printf's which do not
terminate with a "\n".  Should I try to force the issue
with a setbuf(stdout,NULL) in the front of the programs?

--Frank
-------
 6-Aug-86 10:58:19-PDT,969;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Wed 6 Aug 86 10:58:16-PDT
Date: Wed 6 Aug 86 11:58:09-MDT
From: Frank J. Wancho <[email protected]>
Subject: More on setbuf(), etc.
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

The current CLIB causes fopen to fail if the requested mode
is "wr8".  However, "w8" works.  The problem is that when
a new file is fopen'd with just "w8", then any fgetc will
fail because _SIOF_READ is not set.  If you manually set
f->sioflgs |= _SIOF_READ, then setbuf() complains that the
file is not opened for read or write.  Thus, even if fopen
is made to accept "wr8", setbuf will still complain.

In my previous message, I indicated that perhaps I should
use setbuf(stdout,NULL).  I did that and commented out all
the fflush(stdout) lines.  The behavior was still the same
(buffered output)...

--Frank
-------
 6-Aug-86 11:26:01-PDT,597;000000000001
Mail-From: IAN created at  6-Aug-86 11:25:52
Date: Wed 6 Aug 86 11:25:51-PDT
From: Ian Macky <[email protected]>
Subject: Re: printf philosophical question
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

output to stdout starts out being line-buffered and only fflushed
after a newline is output - that is the standard behavior; likewise,
input from stdin is done a line at a time, with editing.  when i want
output to be unbuffered, i usually just send it to stderr.

--ian
-------
 6-Aug-86 11:35:23-PDT,938;000000000001
Mail-From: IAN created at  6-Aug-86 11:35:15
Date: Wed 6 Aug 86 11:35:15-PDT
From: Ian Macky <[email protected]>
Subject: Re: More on setbuf(), etc.
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

the correct syntax for opening a file for read/write is "w+" or "r+"
or something like that.  I don't have any references handy.  "wr" is
definitely wrong.

however, be hereby notified: I/O CURRENTLY ONLY WORKS IN ONE
DIRECTION!  no bi-directional files yet.  but, after looking at what
CARM has to say, it looks easy.  CARM says that you must do a call to
fseek or some such thing BEFORE every direction transition (or have
hit EOF while reading).  once the current problems are taken care of,
i will get on to doing that.

as for setbuf(stdout, NULL), i'll look at it today and see what
the story is.

--ian
-------
 6-Aug-86 13:24:25-PDT,483;000000000001
Mail-From: IAN created at  6-Aug-86 13:24:22
Date: Wed 6 Aug 86 13:24:22-PDT
From: Ian Macky <[email protected]>
Subject: Re: More on setbuf(), etc.
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

when i tested setbuffing stdout to NULL, i had no problems.  output was
unbuffered...    can you provide a minimal code sample that demonstrates
the problem?

--ian
-------
 6-Aug-86 13:45:15-PDT,612;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Wed 6 Aug 86 13:45:04-PDT
Date: Wed 6 Aug 86 14:44:35-MDT
From: Frank J. Wancho <[email protected]>
Subject: Re: More on setbuf(), etc.
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

#include <stdio.h>

main()
{
	setbuf (stdout, NULL);
	printf ("This is the first part of the line...(pause)");
/*	fflush (stdout); */
	sleep (20);
	printf ("...and here's the rest.\n");
}
-------
 6-Aug-86 14:40:35-PDT,605;000000000001
Mail-From: IAN created at  6-Aug-86 14:40:31
Date: Wed 6 Aug 86 14:40:30-PDT
From: Ian Macky <[email protected]>
Subject: Re: More on setbuf(), etc.
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

the setbuf problem has been fixed.  [SRI-NIC]C:CLIB.REL contains
the latest CLIB... more work is under progress.  my tests of
ftell/fseek have been on input files, which is probably why it
works for me and not you.  apparently it's broken for output
files.  i'll fix that next.

--ian
-------
 6-Aug-86 19:19:15-PDT,632;000000000001
Mail-From: KLH created at  6-Aug-86 19:19:10
Date: Wed 6 Aug 86 19:19:09-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: printf philosophical question
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

stdout on V6 and I think V7 Unix was normally unbuffered.  However,
for 4.2BSD it was line buffered for efficiency reasons.  The buffer is
also flushed (or should be) whenever stdin input is asked for.
Using setbuf as you mention is the correct way to ensure a stream is
unbuffered.
-------
12-Aug-86 18:07:03-PDT,774;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Tue 12 Aug 86 18:06:59-PDT
Date: Tue 12 Aug 86 19:06:23-MDT
From: Frank J. Wancho <[email protected]>
Subject: system()?
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

In the old sources library, there was an implementation
of system() I wrote, hoping to see it incorporated into
the library.  I believe it has several advantages in
certain situations.  I wrote it out of necessity for one
situation I had encountered at the time.  Has any consideration
been recently given to merge it in?  Would you consider it,
perhaps, due to its apparently non-standard nature, as an
extension?

Thanks,
Frank
-------
14-Aug-86 13:11:24-PDT,904;000000000001
Mail-From: KLH created at 14-Aug-86 13:11:19
Date: Thu 14 Aug 86 13:11:18-PDT
From: Ken Harrenstien <[email protected]>
Subject: system()
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

I have resurrected system() and re-wrote it to use the existing
vfork() and execl() calls instead of doing its own parsing and
assembler hacking.  I looked at the EXEC itself but don't see any way
it can be invoked to execute a single command line, short of messing
around with it.  The only general method would be to use PTYs, which
is far messier and not something I am inclined to tackle.  I agree
that the current half-way implementation (interpret 1st word as
program name and invoke it) should be sufficient.

This will be included in the next build of the library.  I'll mail
you the code itself separately so you don't have to wait.
-------
15-Aug-86 00:19:53-PDT,935;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Fri 15 Aug 86 00:19:51-PDT
Date: Fri 15 Aug 86 01:19:24-MDT
From: Frank J. Wancho <[email protected]>
Subject: Re: system()
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Ken,

That for the code and for including the function
in the library.  I do wish to point out that although
your code produces the same effect, it ends up using
what I consider an extraneous extra fork and the extra
system resources.  I guess what I was lobbying for is
an additional option in the low level assembler code
which will allow for waiting for the exec'd fork to
return at that level, skipping the necessity of using
the vfork call altogether.  Otherwise, your code is
quite satisfactory.

Thanks,
Frank
-------
15-Aug-86 00:44:35-PDT,1317;000000000001
Mail-From: KLH created at 15-Aug-86 00:44:33
Date: Fri 15 Aug 86 00:44:33-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: system()
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

I don't quite understand.  Both versions use a single inferior fork.
Where does the "extra" one come from?  Remember that execl GETs a program
into the current fork rather than creating another one -- i.e. it "chains".

It is true that the vfork+execl combination is a little bit slower
than a cfork/get since the monitor is setting up a page map for the
new fork which is immediately discarded.  However, at least with vfork
(a 4.2BSD function) no pages are actually copied, and it seems to work
pretty fast.  One advantage of using execl is that it takes care of
the program filename setup and GTJFNing in a consistent way.

One problem with a generic TOPS-20 routine to run-prog-in-new-fork
("pfork" comes close) is that there are two ways of providing a new
fork with arguments (RSCAN and PRARG) and there will probably be a
third if and when UNIX general-purpose arguments (for the argv and
envp vectors to main()) are implemented.  I'm thinking about it at the
moment.
-------
16-Aug-86 12:33:52-PDT,1646;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sat 16 Aug 86 12:33:48-PDT
Date: Sat 16 Aug 86 13:32:52-MDT
From: Frank J. Wancho <[email protected]>
Subject: Misunderstanding?
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

Thanks, with your help, I now have this port about 95% working.  The
remaining 5% concerns the processing of more than one input file by
the program to add the file to the output file.  I think I've narrowed
down the section of code where I introduced a workaround to get past a
compiler complaint as the cause of the runtime problem.

What follows is the code fragments involved in the change I made.
(Note that this code appears to work correctly only if called once.)
I would very much appreciate what code I should use instead of my
apparently incorrect workaround.  (The original two lines are inside
the #ifdef COMMENT envelope.)

Thanks,
Frank
--------------------

static struct entry {		/* string table entry format */
    char    used;		/* true when this entry is in use */
    unsigned int    next;	/* ptr to next in collision list */
    unsigned int    predecessor;/* code for preceeding string */
    unsigned char   follower;	/* char following string */
}                   strtab[TABSIZE];/* the code string table */

#ifdef COMMENT
static long *htab = strtab;	/* hash code table	(crunch) */
static unsigned char   *suffix = strtab;/* suffix table (uncrunch) */
#endif

static long htab[TABSIZE];
static unsigned char suffix[TABSIZE];

====================
-------
16-Aug-86 20:16:31-PDT,1090;000000000001
Mail-From: KLH created at 16-Aug-86 20:16:29
Date: Sat 16 Aug 86 20:16:29-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Misunderstanding?
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Well one problem is that the two declarations are completely different.
The original (commented-out) declarations say htab is a pointer to long,
and suffix is a pointer to unsigned char, and tries to initialize the
pointers with an incorrect type.  The new (presumably) declarations say
htab is an array of longs, and suffix is an array of unsigned chars.
They are not pointers.  
The proper way to initialize them would be something like this:
	static long *htab = (long *) strtab;
	static unsigned char *suffix = (unsigned char *) strtab;

In other words, use a cast to get the initialization type correct.  Note
that not all compilers will support cast expressions in static initializations;
that code is somewhat nonportable to begin with.
-------
17-Aug-86 08:44:34-PDT,41847;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sun 17 Aug 86 08:44:04-PDT
Date: Sun 17 Aug 86 09:42:52-MDT
From: Frank J. Wancho <[email protected]>
Subject: Re: Misunderstanding?
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Ken,

Your suggested changes passed the compiler, but produced completely
incorrect results at runtime.  According to the comments, the intended
action was to reuse the address space taken up by strtab for those two
statics.  It seems that I presented the code too much out of context
in trying to avoid the other extreme presented here...

Here are the three files involved.  Where I had to change things, the
original code is inside #ifdef COMMENT.  The calling sequence is that
addarc is called from main with the pointer to the command line args
shifted to point to the list of files to be added.  addarc calls
addbunch, which calls addfile for each file found in the possibly
wildcarded list of args.  Perhaps the "real" problem stems from the
changes I made around the use of char **path and char **name, and the
associated free statements which I commented out.  Then again, it may
be related to the initialization/cleanup routines with those statics
in ARCLZW.C.

Anyway, all the functions so far are in the first file, ARCADD.C.
addfile calls pack, in the second source file, ARCPAC.C.  pack tries
all compression techniques on the file and selects the one with the
shortest compressed file length, which always seems to end up being
"crunched".  The crunch technique is implemented in the third file,
ARCLZW.C, from which the previous extracts I sent you were taken.

When this process seems to hang, it appears to be in a loop in putcm
when processing the second file in the list of wildcard file names.
The current executable is SYS:TARC.EXE, and the command line is:

TARC A TEST ARC*.C

which creates TEST.TMP, which is renamed to TEST.ARC upon successful
completion.  The intermediate working file containing the current
crunched contents into which putcm writes on the first test pass is
ARCTEMP.CRN.

Again, your help with this is appreciated!

Thanks,
Frank
--------------------

ARCADD.C:

/*  ARC - Archive utility - ARCADD

#define TAG $$segment(@1,$$index(@1,=)+1)
#define VERSION Version TAG(
TED_VERSION DB =3.39), created on TAG(
TED_DATE DB =02/05/86) at TAG(
TED_TIME DB =22:21:53)
#undefine TAG
    VERSION

(C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED

    By:  Thom Henderson

    Description:
	 This file contains the routines used to add files to an archive.

    Language:
	 Computer Innovations Optimizing C86
*/
#include <stdio.h>
#include "arc.h"

addarc (num, arg, move, update, fresh)/* add files to archive */
int     num;			/* number of arguments */
char   *arg[];			/* pointers to arguments */
int     move;			/* true if moving file */
int     update;			/* true if updating */
int     fresh;			/* true if freshening */
{
    char   *d, *dir ();		/* directory junk */
    char    buf[STRLEN];	/* pathname buffer */
#ifdef COMMENT
    char **path = NULL;		/* pointer to pointers to paths */
    char **name = NULL;		/* pointer to pointers to names */
#else
    char   *path[500];		/* pointer to pointers to paths */
    char   *name[500];		/* pointer to pointers to names */
#endif
    int     nfiles = 0;		/* number of files in lists */
    int     notemp;		/* true until a template works */
    int     nowork = 1;		/* true until files are added */
    char   *i, *rindex ();	/* string indexing junk */
    char   *malloc (), *realloc ();/* memory allocators */
    char   *calloc ();
    int     m, n;		/* indices */
#ifdef COMMENT
    unsigned int coreleft();	/* remaining memory reporter */
#endif

    if (num < 1) {		/* if no files named */
	num = 1;		/* then fake one */
	arg[0] = "*.*";		/* add everything */
    }

    for (n = 0; n < num; n++) {	/* for each template supplied */
	strcpy (buf, arg[n]);	/* get ready to fix path */
	if (!(i = rindex (buf, '\\')))
	    if (!(i = rindex (buf, '/')))
		if (!(i = rindex (buf, ':')))
		    i = buf - 1;
	i++;			/* pointer to where name goes */

	notemp = 1;		/* reset files flag */
	for (d = dir (arg[n], 0); *d; d = dir (NULL, 0)) {
	    notemp = 0;		/* template is giving results */
	    nfiles++;		/* add each matching file */
#ifdef COMMENT
	    path = (char **) realloc ((char *) path, nfiles * sizeof(char **));
	    name = (char **) realloc ((char *) name, nfiles * sizeof(char **));
#endif
	    strcpy (i, d);	/* put name in path */
	    path[nfiles - 1] = malloc (strlen (buf) + 1);
	    strcpy (path[nfiles - 1], buf);
	    name[nfiles - 1] = malloc (strlen (d) + 1);
	    strcpy (name[nfiles - 1], d);	/* save name */
	}
	if (notemp && warn)
	    printf ("No files match: %s\n", arg[n]);
    }

    if (nfiles) {
	nfiles = addbunch (nfiles, path, name, move, update, fresh);
	nowork = nowork && !nfiles;
#ifdef COMMENT
	while (nfiles) {
	    free (path[--nfiles]);
	    free (name[nfiles]);
	}
	free (path);
	free (name);
#endif
    }

    if (nowork && warn)
	printf ("No files were added.\n");
}

int     addbunch (nfiles, path, name, move, update, fresh)
				/* add a bunch of files */
int     nfiles;			/* number of files to add */
char  **path;			/* pointers to pathnames */
char  **name;			/* pointers to filenames */
int     move;			/* true if moving file */
int     update;			/* true if updating */
int     fresh;			/* true if freshening */
{
    char    buf[STRLEN];	/* pathname buffer */
    int     m, n;		/* indices */
    char   *d;			/* swap pointer */
    struct heads    hdr;	/* file header data storage */

    for (n = 0; n < nfiles - 1; n++) {/* sort the list of names */
	for (m = n + 1; m < nfiles; m++) {
	    if (strcmp (name[n], name[m]) > 0) {
		d = path[n];
		path[n] = path[m];
		path[m] = d;
		d = name[n];
		name[n] = name[m];
		name[m] = d;
	    }
	}
    }

    for (n = 0; n < nfiles - 1;) {/* consolidate the list of names */
	if (!strcmp (path[n], path[n + 1])/* if duplicate names */
		||!strcmp (path[n], arcname)/* or this archive */
		||!strcmp (path[n], newname)/* or the new version */
		||!strcmp (path[n], bakname)) {/* or its backup */
#ifdef COMMENT
	    free (path[n]);	/* then forget the file */
	    free (name[n]);
#endif
	    for (m = n; m < nfiles - 1; m++) {
		path[m] = path[m + 1];
		name[m] = name[m + 1];
	    }
	    nfiles--;
	}
	else
	    n++;		/* else test the next one */
    }

    if (!strcmp (path[n], arcname)/* special check for last file */
	    ||!strcmp (path[n], newname)/* courtesy of Rick Moore */
	    ||!strcmp (path[n], bakname)) {
#ifdef COMMENT
	free (path[n]);
	free (name[n]);
#endif
	nfiles--;
    }

    if (!nfiles)		/* make sure we got some */
	return 0;

    for (n = 0; n < nfiles - 1; n++)/* watch out for duplicate names */
	if (!strcmp (name[n], name[n + 1])) {
#ifdef COMMENT
	    abort("Duplicate filenames:\n  %s\n  %s",path[n],path[n+1]);
#else
	    printf ("Duplicate filenames:\n  %s\n  %s", name[n], name[n + 1]);
	    exit (1);
#endif
	}

    openarc (1);		/* open archive for changes */

    for (n = 0; n < nfiles; n++)/* add each file in the list */
	addfile (path[n], name[n], update, fresh);

 /* now we must copy over all files that follow our additions */

    while (readhdr (&hdr, arc)) {/* while more entries to copy */
	writehdr (&hdr, new);
	filecopy (arc, new, hdr.size);
    }
    hdrver = 0;			/* archive EOF type */
    writehdr (&hdr, new);	/* write out our end marker */
    closearc (1);		/* close archive after changes */

    if (move) {			/* if this was a move */
	for (n = 0; n < nfiles; n++) {/* then delete each file added */
	    if (unlink (path[n]) && warn) {
		printf ("Cannot unsave %s\n", path[n]);
		nerrs++;
	    }
	}
    }

    return nfiles;		/* say how many were added */
}

static  addfile (path, name, update, fresh)
				/* add named file to archive */
char   *path;			/* path name of file to add */
char   *name;			/* name of file to add */
int     update;			/* true if updating */
int     fresh;			/* true if freshening */
{
    struct heads    nhdr;	/* data regarding the new file */
    struct heads    ohdr;	/* data regarding an old file */
    FILE   *f, *fopen ();	/* file to add, opener */
    long    starts, ftell ();	/* file locations */
    int     c;			/* one char of file */
    int     upd = 0;		/* true if replacing an entry */

    if (!(f = fopen (path, "rC-"))) {
	if (warn) {
	    printf ("Cannot read file: %s\n", path);
	    nerrs++;
	}
	return;
    }

    strcpy (nhdr.name, name);	/* save name */
    nhdr.size = 0;		/* clear out size storage */
    nhdr.crc = 0;		/* clear out CRC check storage */
    getstamp (f, &nhdr.date, &nhdr.time);

 /* position archive to spot for new file */

    if (arc) {			/* if adding to existing archive */
	starts = ftell (arc);	/* where are we? */
	while (readhdr (&ohdr, arc)) {/* while more files to check */
	    if (!strcmp (ohdr.name, nhdr.name)) {
		upd = 1;	/* replace existing entry */
		if (update || fresh) {/* if updating or freshening */
		    if (nhdr.date < ohdr.date
			    || (nhdr.date == ohdr.date && nhdr.time <= ohdr.time)) {
			fseek (arc, starts, 0);
			fclose (f);
			return;	/* skip if not newer */
		    }
		}
	    }

	    if (strcmp (ohdr.name, nhdr.name) >= 0)
		break;		/* found our spot */

	    writehdr (&ohdr, new);/* entry preceeds update; keep it */
	    filecopy (arc, new, ohdr.size);
	    starts = ftell (arc);/* now where are we? */
	}

	if (upd) {		/* if an update */
	    if (note)
		printf ("Updating file: %-12s  ", name);
	    fseek (arc, ohdr.size, 1);
	}
	else
	    if (fresh) {	/* else if freshening */
		fseek (arc, starts, 0);/* then do not add files */
		fclose (f);
		return;
	    }
	    else {		/* else adding a new file */
		if (note)
		    printf ("Adding file:   %-12s  ", name);
		fseek (arc, starts, 0);/* reset for next time */
	    }
    }

    else {			/* no existing archive */
	if (fresh) {		/* cannot freshen nothing */
	    fclose (f);
	    return;
	}
	else
	    if (note)		/* else adding a file */
		printf ("Adding file:   %-12s  ", name);
    }

    starts = ftell (new);	/* note where header goes */
    hdrver = ARCVER;		/* anything but end marker */
    writehdr (&nhdr, new);	/* write out header skeleton */
    pack (f, new, &nhdr);	/* pack file into archive */
    fseek (new, starts, 0);	/* move back to header skeleton */
    writehdr (&nhdr, new);	/* write out real header */
    fseek (new, nhdr.size, 1);	/* skip over data to next header */
    fclose (f);			/* all done with the file */
}
--------------------

ARCPAC.C:

/*  ARC - Archive utility - ARCPACK

#define TAG $$segment(@1,$$index(@1,=)+1)
#define VERSION Version TAG(
TED_VERSION DB =3.37), created on TAG(
TED_DATE DB =02/03/86) at TAG(
TED_TIME DB =22:58:01)
#undefine TAG
    VERSION

(C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED

    By:  Thom Henderson

    Description:
	 This file contains the routines used to compress a file
	 when placing it in an archive.

    Language:
	 Computer Innovations Optimizing C86
*/
#include <stdio.h>
#include "arc.h"

/* stuff for non-repeat packing */

#define DLE 0x90		/* repeat sequence marker */

static unsigned char    state;	/* current packing state */

/* non-repeat packing states */

#define NOHIST  0		/* don't consider previous input */
#define SENTCHAR 1		/* lastchar set, no lookahead yet */
#define SENDNEWC 2		/* run over, send new char next */
#define SENDCNT 3		/* newchar set, send count next */

/* packing results */

static long stdlen;		/* length for standard packing */
static int  crcval;		/* CRC check value */

pack (f, t, hdr)		/* pack file into an archive */
FILE   *f, *t;			/* source, destination */
struct heads   *hdr;		/* pointer to header data */
{
    int     c;			/* one character of stream */
    long    ncrlen;		/* length after packing */
    long    huflen;		/* length after squeezing */
    long    lzwlen;		/* length after crunching */
    long    pred_sq (), file_sq ();/* stuff for squeezing */
    long    pred_cm ();		/* dynamic crunching cleanup */
    char    tnam[STRLEN];	/* temporary name buffer */
    char   *makefnam ();	/* filename fixer upper */
    FILE   *crn = NULL;		/* temporary crunch file */

 /* first pass - see which method is best */

    if (!nocomp) {		/* if storage kludge not active */
	if (note)
	    printf (" analyzing, ");

	if (arctemp)		/* use temp area if specified */
	    sprintf (tnam, "%sARCTEMP.CRN", arctemp);
	else
	    makefnam ("ARCTEMP.CRN", arcname, tnam);
	crn = fopen (tnam, "w8");

	state = NOHIST;		/* initialize ncr packing */
	stdlen = ncrlen = 0;	/* reset size counters */
	crcval = 0;		/* initialize CRC check value */
	setcode ();		/* initialize encryption */

	initcm (f, crn);	/* initialize for crunching */
	initsq ();		/* initialize for squeeze scan */

	while ((c = getncr (f)) != EOF) {/* for each byte of file */
	    ncrlen++;		/* one more packed byte */
	    scan_sq (c);	/* see what squeezing can do */
	    putcm (c, crn);	/* see what crunching can do */
	}
	huflen = pred_sq ();	/* finish up after squeezing */
	lzwlen = pred_cm (crn);	/* finish up after crunching */
    }
    else {			/* else kludge the method */
	stdlen = 0;		/* make standard look best */
	ncrlen = huflen = lzwlen = 1;
    }

 /* standard set-ups common to all methods */

    fseek (f, 0L, 0);		/* rewind input */
    hdr -> crc = crcval;	/* note CRC check value */
    hdr -> length = stdlen;	/* set actual file length */
    state = NOHIST;		/* reinitialize ncr packing */
    setcode ();			/* reinitialize encryption */

 /* choose and use the shortest method */

    if (stdlen <= ncrlen && stdlen <= huflen && stdlen <= lzwlen) {
	if (kludge)		/* DEBUG */
	    printf ("(%ld) ", lzwlen - stdlen);
	if (note)
	    printf ("storing, ");/* store without compression */
	hdrver = 2;		/* note packing method */
	stdlen = crcval = 0;	/* recalc these for kludge */
	while ((c = getch (f)) != EOF)/* store it straight */
	    putpak (c, t);
	hdr -> crc = crcval;
	hdr -> length = hdr -> size = stdlen;
    }

    else
	if (ncrlen < huflen && ncrlen < lzwlen) {
	    if (kludge)		/* DEBUG */
		printf ("(%ld) ", lzwlen - ncrlen);
	    if (note)
		printf ("packing, ");/* pack with repeat suppression */
	    hdrver = 3;		/* note packing method */
	    hdr -> size = ncrlen;/* set data length */
	    while ((c = getncr (f)) != EOF)
		putpak (c, t);
	}

	else
	    if (huflen < lzwlen) {
		if (kludge)	/* DEBUG */
		    printf ("(%ld) ", lzwlen - huflen);
		if (note)
		    printf ("squeezing, ");
		hdrver = 4;	/* note packing method */
		hdr -> size = file_sq (f, t);/* note final size */
	    }

	    else {
		if (kludge)	/* DEBUG */
		    printf ("(%ld) ", huflen - lzwlen);
		if (note)
		    printf ("crunching, ");
		hdrver = 8;
		hdr -> size = lzwlen;/* size should not change */
		if (crn) {	/* if temp was created */
/*		    fseek (crn, 0L, 0); */
		    fclose (crn);
		    crn = fopen (tnam, "r");
				/* then copy over crunched temp */
		    while ((c = fgetc (crn)) != EOF)
			puttst (c, t);
		}
		else {		/* else re-crunch */
		    initcm (f, t);
		    while ((c = getncr (f)) != EOF)
			putcm (c, t);
		    pred_cm (t);/* finish up after crunching */
		}
	    }

 /* standard cleanups common to all methods */

    if (crn) {			/* get rid of crunch temporary */
	fclose (crn);
	if (unlink (tnam) && warn) {
	    printf ("Cannot delete temporary file %s\n", tnam);
	    nerrs++;
	}
    }
    if (note)
	printf ("done.\n");
}

/*  Non-repeat compression - text is passed through normally, except that
    a run of more than two is encoded as:

	 <char> <DLE> <count>

    Special case: a count of zero indicates that the DLE is really a DLE,
    not a repeat marker.
*/

int     getncr (f)		/* get bytes with collapsed runs */
FILE   *f;			/* file to get from */
{
    static int  lastc;		/* value returned on last call */
    static int  repcnt;		/* repetition counter */
    static int  c;		/* latest value seen */

    switch (state) {		/* depends on our state */
	case NOHIST: 		/* no relevant history */
	    state = SENTCHAR;
	    return lastc = getch (f);/* remember the value next time */

	case SENTCHAR: 		/* char was sent. look ahead */
	    switch (lastc) {	/* action depends on char */
		case DLE: 	/* if we sent a real DLE */
		    state = NOHIST;/* then start over again */
		    return 0;	/* but note that the DLE was real */

		case EOF: 	/* EOF is always a special case */
		    return EOF;

		default: 	/* else test for a repeat */
		    for (repcnt = 1; (c = getch (f)) == lastc && repcnt < 255; repcnt++);
				/* find end of run */

		    switch (repcnt) {/* action depends on run size */
			case 1: /* not a repeat */
			    return lastc = c;
				/* but remember value next time */

			case 2: /* a repeat, but too short */
			    state = SENDNEWC;
				/* send the second one next time */
			    return lastc;

			default: /* a run - compress it */
			    state = SENDCNT;
				/* send repeat count next time */
			    return DLE;/* send repeat marker this time */
		    }
	    }

	case SENDNEWC: 		/* send second char of short run */
	    state = SENTCHAR;
	    return lastc = c;

	case SENDCNT: 		/* sent DLE, now send count */
	    state = SENDNEWC;
	    return repcnt;

	default: 
	    printf ("Bug - bad ncr state\n");
	    exit (1);
    }
}

static int  getch (f)		/* special get char for packing */
FILE   *f;			/* file to get from */
{
    int     c;			/* a char from the file */

    if ((c = fgetc (f)) != EOF) {/* if not the end of file */
	crcval = addcrc (crcval, c);/* then update CRC check value */
	stdlen++;		/* and bump length counter */
    }

    return c;
}

putpak (c, f)			/* put a packed byte into archive */
char    c;			/* byte to put */
FILE   *f;			/* archive to put it in */
{
    puttst (code (c), f);	/* put encoded byte, with checks */
}
--------------------

ARCLZW.C:

/*  ARC - Archive utility - ARCLZW

#define TAG $$segment(@1,$$index(@1,=)+1)
#define VERSION Version TAG(
TED_VERSION DB =1.88), created on TAG(
TED_DATE DB =01/20/86) at TAG(
TED_TIME DB =16:47:04)
#undefine TAG
    VERSION

(C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED

    By:  Thom Henderson

    Description:
	 This file contains the routines used to implement Lempel-Zev
	 data compression, which calls for building a coding table on
	 the fly.  This form of compression is especially good for encoding
	 files which contain repeated strings, and can often give dramatic
	 improvements over traditional Huffman SQueezing.

    Language:
	 Computer Innovations Optimizing C86

    Programming notes:
	 In this section I am drawing heavily on the COMPRESS program
	 from UNIX.  The basic method is taken from "A Technique for High
	 Performance Data Compression", Terry A. Welch, IEEE Computer
	 Vol 17, No 6 (June 1984), pp 8-19.  Also see "Knuth's Fundamental
	 Algorithms", Donald Knuth, Vol 3, Section 6.4.

	 As best as I can tell, this method works by tracing down a hash
	 table of code strings where each entry has the property:

	      if <string> <char> is in the table
	      then <string> is in the table.
*/
#include <stdio.h>
#include "arc.h"

/* definitions for older style crunching */

#define FALSE	 0
#define TRUE	 !FALSE
#define TABSIZE  4096
#define NO_PRED  0xFFFF
#define EMPTY	 0xFFFF
#define NOT_FND  0xFFFF

static unsigned int inbuf;	/* partial input code storage */
static int  sp;			/* current stack pointer */

static struct entry {		/* string table entry format */
    char    used;		/* true when this entry is in use */
    unsigned int    next;	/* ptr to next in collision list */
    unsigned int    predecessor;/* code for preceeding string */
    unsigned char   follower;	/* char following string */
}                   strtab[TABSIZE];/* the code string table */


/* definitions for the new dynamic Lempel-Zev crunching */

#define BITS   12		/* maximum bits per code */
#define HSIZE  5003		/* 80% occupancy */
#define INIT_BITS 9		/* initial number of bits/code */

static int  n_bits;		/* number of bits/code */
static int  maxcode;		/* maximum code, given n_bits */
#define MAXCODE(n)	((1<<(n)) - 1)/* maximum code calculation */
static int  codemax = 1 << BITS;/* largest possible code (+1) */

static char buf[BITS];		/* input/output buffer */

static unsigned char    lmask[9] =/* left side masks */
{   0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00 };

static unsigned char    rmask[9] =/* right side masks */
{   0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};

static int  offset;		/* byte offset for code output */
static long in_count;		/* length of input */
static long bytes_out;		/* length of compressed output */
static unsigned int ent;

/* To save much memory (which we badly need at this point), we overlay
 * the table used by the previous version of Lempel-Zev with those used
 * by the new version.  Since no two of these routines will be used
 * together, we can safely do this.  Note that the tables used for Huffman
 * squeezing may NOT overlay these, since squeezing and crunching are done
 * in parallel.
 */

#ifdef COMMENT
static long *htab = strtab;	/* hash code table	(crunch) */
#else
static long htab[TABSIZE];
#endif
static unsigned int codetab[HSIZE];/* string code table (crunch) */

static unsigned int *prefix = codetab;/* prefix code table (uncrunch) */
#ifdef COMMENT
static unsigned char   *suffix = strtab;/* suffix table (uncrunch) */
#else
static unsigned char suffix[TABSIZE];
#endif

static int  free_ent;		/* first unused entry */
static int  frstcmp;		/* true at start of compression */
static unsigned char    stack[HSIZE];/* local push/pop stack */

/*
 * block compression parameters -- after all codes are used up,
 * and compression rate changes, start over.
 */

static int  clear_flg;
static long ratio;
#define CHECK_GAP 10000		/* ratio check interval */
static long checkpoint;

/*
 * the next two codes should not be changed lightly, as they must not
 * lie within the contiguous general code space.
 */
#define FIRST	257		/* first free entry */
#define CLEAR	256		/* table clear output code */

static  cl_block (t)		/* table clear for block compress */
FILE   *t;			/* our output file */
{
    long int    rat;

    checkpoint = in_count + CHECK_GAP;

    if (in_count > 0x007fffff) {/* shift will overflow */
	rat = bytes_out >> 8;
	if (rat == 0)		/* Don't divide by zero */
	    rat = 0x7fffffff;
	else
	    rat = in_count / rat;
    }
    else
	rat = (in_count << 8) / bytes_out;/* 8 fractional bits */

    if (rat > ratio)
	ratio = rat;
    else {
	ratio = 0;
	setmem (htab, HSIZE * sizeof (long), 0xff);
	free_ent = FIRST;
	clear_flg = 1;
	putcode (CLEAR, t);
    }
}

/*****************************************************************
 *
 * Output a given code.
 * Inputs:
 *	code:	A n_bits-bit integer.  If == -1, then EOF.  This assumes
 *		that n_bits =< (long)wordsize - 1.
 * Outputs:
 *	Outputs code to the file.
 * Assumptions:
 *	Chars are 8 bits long.
 * Algorithm:
 *	Maintain a BITS character long buffer (so that 8 codes will
 * fit in it exactly).  When the buffer fills up empty it and start over.
 */

static  putcode (code, t)	/* output a code */
int     code;			/* code to output */
FILE   *t;			/* where to put it */
{
    int     r_off = offset;	/* right offset */
    int     bits = n_bits;	/* bits to go */
    char   *bp = buf;		/* buffer pointer */
    int     n;			/* index */

    if (code >= 0) {		/* if a real code *//* 
				 * Get to the first byte.
				 */
	bp += (r_off >> 3);
	r_off &= 7;

 /* 
  * Since code is always >= 8 bits, only need to mask the first
  * hunk on the left.
  */
	*bp = (*bp & rmask[r_off]) | (code << r_off) & lmask[r_off];
	bp++;
	bits -= (8 - r_off);
	code >>= (8 - r_off);

 /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
	if (bits >= 8) {
	    *bp++ = code;
	    code >>= 8;
	    bits -= 8;
	}

 /* Last bits. */
	if (bits)
	    *bp = code;

	offset += n_bits;

	if (offset == (n_bits << 3)) {
	    bp = buf;
	    bits = n_bits;
	    bytes_out += bits;
	    do
		putpak (*bp++, t);
	    while (--bits);
	    offset = 0;
	}

 /* 
  * If the next entry is going to be too big for the code size,
  * then increase it, if possible.
  */
	if (free_ent > maxcode || clear_flg > 0) {/* 
				 * Write the whole buffer, because the input side won't
				 * discover the size increase until after it has read it.
				 */
	    if (offset > 0) {
		bp = buf;	/* reset pointer for writing */
		bytes_out += n = n_bits;
		while (n--)
		    putpak (*bp++, t);
	    }
	    offset = 0;

	    if (clear_flg) {	/* reset if clearing */
		maxcode = MAXCODE (n_bits = INIT_BITS);
		clear_flg = 0;
	    }
	    else {		/* else use more bits */
		n_bits++;
		if (n_bits == BITS)
		    maxcode = codemax;
		else
		    maxcode = MAXCODE (n_bits);
	    }
	}
    }

    else {			/* dump the buffer on EOF */
	bytes_out += n = (offset + 7) / 8;

	if (offset > 0)
	    while (n--)
		putpak (*bp++, t);
	offset = 0;
    }
}

/*****************************************************************
 *
 * Read one code from the standard input.  If EOF, return -1.
 * Inputs:
 *	cmpin
 * Outputs:
 *	code or -1 is returned.
 */

static int  getcode (f)		/* get a code */
FILE   *f;			/* file to get from */
{
    int     code;
    static int  offset = 0, size = 0;
    int     r_off, bits;
    unsigned char  *bp = buf;

    if (clear_flg > 0 || offset >= size || free_ent > maxcode) {/* 
				 * If the next entry will be too big for the current code
				 * size, then we must increase the size.  This implies reading
				 * a new buffer full, too.
				 */
	if (free_ent > maxcode) {
	    n_bits++;
	    if (n_bits == BITS)
		maxcode = codemax;/* won't get any bigger now */
	    else
		maxcode = MAXCODE (n_bits);
	}
	if (clear_flg > 0) {
	    maxcode = MAXCODE (n_bits = INIT_BITS);
	    clear_flg = 0;
	}

	for (size = 0; size < n_bits; size++) {
	    if ((code = getunp (f)) == EOF)
		break;
	    else
		buf[size] = code;
	}
	if (size <= 0)
	    return -1;		/* end of file */

	offset = 0;
 /* Round size down to integral number of codes */
	size = (size << 3) - (n_bits - 1);
    }
    r_off = offset;
    bits = n_bits;

 /* 
  * Get to the first byte.
  */
    bp += (r_off >> 3);
    r_off &= 7;

 /* Get first part (low order bits) */
    code = (*bp++ >> r_off);
    bits -= 8 - r_off;
    r_off = 8 - r_off;		/* now, offset into code word */

 /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
    if (bits >= 8) {
	code |= *bp++ << r_off;
	r_off += 8;
	bits -= 8;
    }
 /* high order bits. */
    code |= (*bp & rmask[bits]) << r_off;
    offset += n_bits;

    return code;
}

/*
 * compress a file
 *
 * Algorithm:  use open addressing double hashing (no chaining) on the
 * prefix code / next character combination.  We do a variant of Knuth's
 * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
 * secondary probe.  Here, the modular division first probe is gives way
 * to a faster exclusive-or manipulation.  Also do block compression with
 * an adaptive reset, where the code table is cleared when the compression
 * ratio decreases, but after the table fills.  The variable-length output
 * codes are re-sized at this point, and a special CLEAR code is generated
 * for the decompressor.
 */

initcm (f, t)			/* initialize for compression */
FILE   *f;			/* file we will be compressing */
FILE   *t;			/* where we will put it */
{
    offset = 0;
    bytes_out = 1;
    clear_flg = 0;
    ratio = 0;
    in_count = 1;
    checkpoint = CHECK_GAP;
    maxcode = MAXCODE (n_bits = INIT_BITS);
    free_ent = FIRST;
    setmem (htab, HSIZE * sizeof (long), 0xff);
    n_bits = INIT_BITS;		/* set starting code size */

    putpak (BITS, t);		/* note our max code length */

    frstcmp = 1;		/* next byte will be first */
}

putcm (c, t)			/* compress a character */
unsigned char   c;		/* character to compress */
FILE   *t;			/* where to put it */
{
    static long fcode;
    static int  hshift;
    int     i;
    int     disp;

    if (frstcmp) {		/* special case for first byte */
	ent = c;		/* remember first byte */

	hshift = 0;
	for (fcode = (long) HSIZE; fcode < 65536L; fcode *= 2L)
	    hshift++;
	hshift = 8 - hshift;	/* set hash code range bound */

	frstcmp = 0;		/* no longer first */
	return;
    }

    in_count++;
    fcode = (long) (((long) c << BITS) + ent);
    i = (c << hshift) ^ ent;	/* xor hashing */

    if (htab[i] == fcode) {
	ent = codetab[i];
	return;
    }
    else
	if (htab[i] < 0)	/* empty slot */
	    goto nomatch;
    disp = HSIZE - i;		/* secondary hash (after G.Knott) */
    if (i == 0)
	disp = 1;

probe: 
    if ((i -= disp) < 0)
	i += HSIZE;

    if (htab[i] == fcode) {
	ent = codetab[i];
	return;
    }
    if (htab[i] > 0)
	goto probe;

nomatch: 
    putcode (ent, t);
    ent = c;
    if (free_ent < codemax) {
	codetab[i] = free_ent++;/* code -> hashtable */
	htab[i] = fcode;
    }
    else
	if ((long int) in_count >= checkpoint)
	    cl_block (t);
}

long    pred_cm (t)		/* finish compressing a file */
FILE   *t;			/* where to put it */
{
    putcode (ent, t);		/* put out the final code */
    putcode (-1, t);		/* tell output we are done */

    return bytes_out;		/* say how big it got */
}

/*
 * Decompress a file.  This routine adapts to the codes in the file
 * building the string table on-the-fly; requiring no table to be stored
 * in the compressed file.  The tables used herein are shared with those of
 * the compress() routine.  See the definitions above.
 */

decomp (f, t)			/* decompress a file */
FILE   *f;			/* file to read codes from */
FILE   *t;			/* file to write text to */
{
    unsigned char  *stackp;
    int     finchar;
    int     code, oldcode, incode;

    if ((code = getunp (f)) != BITS) {
	printf ("File packed with %d bits, I can only handle %d", code, BITS);
	exit (1);
    }

    n_bits = INIT_BITS;		/* set starting code size */
    clear_flg = 0;

 /* 
  * As above, initialize the first 256 entries in the table.
  */
    maxcode = MAXCODE (n_bits = INIT_BITS);
    for (code = 255; code >= 0; code--) {
	prefix[code] = 0;
	suffix[code] = (unsigned char) code;
    }
    free_ent = FIRST;

    finchar = oldcode = getcode (f);
    if (oldcode == -1)		/* EOF already? */
	return;			/* Get out of here */
    putncr ((char) finchar, t);	/* first code must be 8 bits=char */
    stackp = stack;

    while ((code = getcode (f)) > -1) {
	if (code == CLEAR) {
	    for (code = 255; code >= 0; code--)
		prefix[code] = 0;
	    clear_flg = 1;
	    free_ent = FIRST - 1;
	    if ((code = getcode (f)) == -1)/* O, untimely death! */
		break;
	}
	incode = code;
 /* 
  * Special case for KwKwK string.
  */
	if (code >= free_ent) {
	    *stackp++ = finchar;
	    code = oldcode;
	}

 /* 
  * Generate output characters in reverse order
  */
	while (code >= 256) {
	    *stackp++ = suffix[code];
	    code = prefix[code];
	}
	*stackp++ = finchar = suffix[code];

 /* 
  * And put them out in forward order
  */
	do
	    putncr (*--stackp, t);
	while (stackp > stack);

 /* 
  * Generate the new entry.
  */
	if ((code = free_ent) < codemax) {
	    prefix[code] = (unsigned short) oldcode;
	    suffix[code] = finchar;
	    free_ent = code + 1;
	}
 /* 
  * Remember previous code.
  */
	oldcode = incode;
    }
}


/*************************************************************************
 * Please note how much trouble it can be to maintain upwards		 *
 * compatibility.  All that follows is for the sole purpose of unpacking *
 * files which were packed using an older method.			 *
 *************************************************************************/


/*  The h() pointer points to the routine to use for calculating a hash
    value.  It is set in the init routines to point to either of oldh()
    or newh().

    oldh() calculates a hash value by taking the middle twelve bits
    of the square of the key.

    newh() works somewhat differently, and was tried because it makes
    ARC about 23% faster.  This approach was abandoned because dynamic
    Lempel-Zev (above) works as well, and packs smaller also.  However,
    inadvertent release of a developmental copy forces us to leave this in.
*/

static unsigned (*h) ();	/* pointer to hash function */

static unsigned oldh (pred, foll)/* old hash function */
unsigned int    pred;		/* code for preceeding string */
unsigned char   foll;		/* value of following char */
{
    long    local;		/* local hash value */

    local = (pred + foll) | 0x0800;/* create the hash key */
    local *= local;		/* square it */
    return (local >> 6) & 0x0FFF;/* return the middle 12 bits */
}

static unsigned newh (pred, foll)/* new hash function */
unsigned int    pred;		/* code for preceeding string */
unsigned char   foll;		/* value of following char */
{
    return ((pred + foll) * 15073) & 0xFFF;/* faster hash */
}

/*  The eolist() function is used to trace down a list of entries with
    duplicate keys until the last duplicate is found.
*/

static unsigned eolist (index)	/* find last duplicate */
unsigned int    index;
{
    int     temp;

    while (temp = strtab[index].next)/* while more duplicates */
	index = temp;

    return index;
}

/*  The hash() routine is used to find a spot in the hash table for a new
    entry.  It performs a "hash and linear probe" lookup, using h() to
    calculate the starting hash value and eolist() to perform the linear
    probe.  This routine DOES NOT detect a table full condition.  That
    MUST be checked for elsewhere.
*/

static unsigned hash (pred, foll)/* find spot in the string table */
unsigned int    pred;		/* code for preceeding string */
unsigned char   foll;		/* char following string */
{
    unsigned int    local, tempnext;/* scratch storage */
    struct entry   *ep;		/* allows faster table handling */

    local = (*h) (pred, foll);	/* get initial hash value */

    if (!strtab[local].used)	/* if that spot is free */
	return local;		/* then that's all we need */

    else {			/* else a collision has occured */
	local = eolist (local);	/* move to last duplicate */

 /*   We must find an empty spot. We start looking 101 places down the
    table from the last duplicate. */

	tempnext = (local + 101) & 0x0FFF;
	ep = &strtab[tempnext];	/* initialize pointer */

	while (ep -> used) {	/* while empty spot not found */
	    if (++tempnext == TABSIZE) {/* if we are at the end */
		tempnext = 0;	/* wrap to beginning of table */
		ep = strtab;
	    }
	    else
		++ep;		/* point to next element in table */
	}

 /*   local still has the pointer to the last duplicate, while tempnext
    has the pointer to the spot we found.  We use this to maintain the
    chain of pointers to duplicates. */

	strtab[local].next = tempnext;

	return tempnext;
    }
}

/*  The unhash() function is used to search the hash table for a given key.
    Like hash(), it performs a hash and linear probe search.  It returns
    either the number of the entry (if found) or NOT_FND (if not found).
*/

static unsigned unhash (pred, foll)/* search string table for a key */
unsigned int    pred;		/* code of preceeding string */
unsigned char   foll;		/* character following string */
{
    unsigned int    local, offset;/* scratch storage */
    struct entry   *ep;		/* this speeds up access */

    local = (*h) (pred, foll);	/* initial hash */

    while (1) {
	ep = &strtab[local];	/* speed up table access */

	if ((ep -> predecessor == pred) && (ep -> follower == foll))
	    return local;	/* we have a match */

	if (!ep -> next)	/* if no more duplicates */
	    return NOT_FND;	/* then key is not listed */

	local = ep -> next;	/* move on to next duplicate */
    }
}

/*  The inittab() routine is used to initialize our hash table.
    You realize, of course, that "initialize" is a complete misnomer.
*/

static  inittab () {		/* set ground state in hash table */
    unsigned int    i;		/* table index */

    setmem ((char *) strtab, sizeof (strtab), 0);

    for (i = 0; i < 256; i++)	/* list all single byte strings */
	upd_tab (NO_PRED, i);

    inbuf = EMPTY;		/* nothing is in our buffer */
}

/*  The upd_tab routine is used to add a new entry to the string table.
    As previously stated, no checks are made to ensure that the table
    has any room.  This must be done elsewhere.
*/

upd_tab (pred, foll)		/* add an entry to the table */
unsigned int    pred;		/* code for preceeding string */
unsigned int    foll;		/* character which follows string */
{
    struct entry   *ep;		/* pointer to current entry */

 /* calculate offset just once */

    ep = &strtab[hash (pred, foll)];

    ep -> used = TRUE;		/* this spot is now in use */
    ep -> next = 0;		/* no duplicates after this yet */
    ep -> predecessor = pred;	/* note code of preceeding string */
    ep -> follower = foll;	/* note char after string */
}

/*  This algorithm encoded a file into twelve bit strings (three nybbles).
    The gocode() routine is used to read these strings a byte (or two)
    at a time.
*/

static  gocode (fd)		/* read in a twelve bit code */
FILE   *fd;			/* file to get code from */
{
    unsigned int    localbuf, returnval;

    if (inbuf == EMPTY) {	/* if on a code boundary */
	if ((localbuf = getunp (fd)) == EOF)/* get start of next code */
	    return EOF;		/* pass back end of file status */
	localbuf &= 0xFF;	/* mask down to true byte value */
	if ((inbuf = getunp (fd)) == EOF)
				/* get end of code, start of next */
	    return EOF;		/* this should never happen */
	inbuf &= 0xFF;		/* mask down to true byte value */

	returnval = ((localbuf << 4) & 0xFF0) + ((inbuf >> 4) & 0x00F);
	inbuf &= 0x000F;	/* leave partial code pending */
    }

    else {			/* buffer contains first nybble */
	if ((localbuf = getunp (fd)) == EOF)
	    return EOF;
	localbuf &= 0xFF;

	returnval = localbuf + ((inbuf << 8) & 0xF00);
	inbuf = EMPTY;		/* note no hanging nybbles */
    }
    return returnval;		/* pass back assembled code */
}

static  push (c)		/* push char onto stack */
int     c;			/* character to push */
{
    stack[sp] = ((char) c);	/* coerce integer into a char */

    if (++sp >= TABSIZE) {
	printf ("Stack overflow\n");
	exit (1);
    }
}

static int  pop () {		/* pop character from stack */
    if          (sp > 0)
	return  ((int) stack[--sp]);/* leave ptr at next empty slot */

    else
    return EMPTY;
}

/***** LEMPEL-ZEV DECOMPRESSION *****/

static int  codcnt;		/* needed to detect table full */
static unsigned code;		/* where we are so far */
static int  firstc;		/* true only on first character */

initucr (new)			/* get set for uncrunching */
int     new;			/* true to use new hash function */
{
    if (new)			/* set proper hash function */
	h = newh;
    else
	h = oldh;

    sp = 0;			/* clear out the stack */
    inittab ();			/* set up atomic code definitions */
    codcnt = TABSIZE - 256;	/* note space left in table */
    firstc = 1;			/* true only on first code */
}

int     getucr (f)		/* get next uncrunched byte */
FILE   *f;			/* file containing crunched data */
{
    unsigned int    c;		/* a character of input */
    int     code, newcode;
    static int  oldcode, finchar;
    struct entry   *ep;		/* allows faster table handling */

    if (firstc) {		/* first code is always known */
	firstc = FALSE;		/* but next will not be first */
	oldcode = gocode (f);
	return finchar = strtab[oldcode].follower;
    }

    if (!sp) {			/* if stack is empty */
	if ((code = newcode = gocode (f)) == EOF)
	    return EOF;

	ep = &strtab[code];	/* initialize pointer */

	if (!ep -> used) {	/* if code isn't known */
	    code = oldcode;
	    ep = &strtab[code];	/* re-initialize pointer */
	    push (finchar);
	}

	while (ep -> predecessor != NO_PRED) {
	    push (ep -> follower);/* decode string backwards */
	    code = ep -> predecessor;
	    ep = &strtab[code];
	}

	push (finchar = ep -> follower);/* save first character also */

 /*   The above loop will terminate, one way or another, with
    strtab[code].follower equal to the first character in the string. */

	if (codcnt) {		/* if room left in string table */
	    upd_tab (oldcode, finchar);
	    --codcnt;
	}

	oldcode = newcode;
    }

    return pop ();		/* return saved character */
}
====================
-------
18-Aug-86 08:33:34-PDT,1482;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 18 Aug 86 08:33:23-PDT
Date: Mon 18 Aug 86 09:32:06-MDT
From: Frank J. Wancho <[email protected]>
Subject: New function: mail()?
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

If you recall, I pointed you (Ken) to a package called netlib
used on a Unix system to automatically answer mailed requests
for files.  I took pieces of that program and created a
simple-minded version that takes the contents of the Subject:
line as the filename, runs the file through TARC, uuencodes
the result, splits the resulting file into multiple message
files if >60,000 chars, and is supposed to then feed the message
files to "mail".  mail on Unix systems can take an indirect
filename.  MAIL on our system, and probably yours, is a built-in
EXEC command which starts MM at its second entry point, and
does not take indirect files, nor callable via system().

What I had in mind is a new extended function called mail(),
based on a conversion of <MM>ARMAIL.MAC, which would take
three arguments: to, subject, filename, at its simpliest
level.  Perhaps, at some future time, it could be rigged
to take a pointer to a character array containing most of
the arguments which you can specify for a queued mail file
and either a filename or text for the message body.

What do you think of this idea?

--Frank
-------
18-Aug-86 09:56:46-PDT,431;000000000001
Mail-From: KLH created at 18-Aug-86 09:56:43
Date: Mon 18 Aug 86 09:56:43-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: New function: mail()?
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Seems fine although I would consider it a user utility rather than
part of the "C library".
-------
18-Aug-86 13:00:44-PDT,1589;000000000001
Mail-From: KLH created at 18-Aug-86 13:00:40
Date: Mon 18 Aug 86 13:00:40-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Misunderstanding?
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

I suspect your problem lies with the "setmem" routine.  The source was
not included, but from the calls it looks as if it expects a char pointer
as the first argument.  It is not being given this when called with htab
as an argument, thus htab may never be initialized.  Or vice versa, if
it expects a word address and is given a byte pointer.

The re-use of the strtab array needs to be checked because there are some
places where the code makes assumptions about the size of the re-used
stuff which may or may not be true depending on how large a strtab entry
actually is.  For example the place where setmem is applied to htab
assumes there are (sizeof long)*HSIZE bytes.  Maybe so, maybe not.

You can reinstate the realloc/free calls, if you wish, by inserting a check
for null pointers just before the realloc calls and using malloc instead if
nothing has been allocated yet.  Then you don't have to worry about exceeding
the array bounds, etc.

Your basic problem is that the guy who wrote this stuff wasn't very careful.

Please don't send thousands of lines of source code to BUG-KCC.  Those who
express an interest in looking at a problem can receive the sources directly,
without cluttering up the archive mailboxes etc...
-------
18-Aug-86 18:43:45-PDT,919;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 18 Aug 86 18:43:39-PDT
Date: Mon 18 Aug 86 19:42:44-MDT
From: Frank J. Wancho <[email protected]>
Subject: Re: New function: mail()?
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Ken,

Perhaps a "reasonable" basis to start a utility is SNDMAI.MAC,
which is part of the REMIND package we use here.  It is a
subroutine that takes an address of an argument block in AC1.
Unfortunately, it expects a string pointer for the message
body, which probably means the envelope would have to PMAP in
the file.  It would probably still make a good C function as
it stands (more or less).  Now, all we need is a way to PMAP
an entire file and point to it as a huge string...

--Frank
-------
18-Aug-86 18:49:58-PDT,983;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 18 Aug 86 18:49:55-PDT
Date: Mon 18 Aug 86 19:49:00-MDT
From: Frank J. Wancho <[email protected]>
Subject: Re: Misunderstanding?
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Ken,

Sorry for the long file.  I guess it was a sign of frustration.

I believe you have a valid point concerning setmem.  However,
I just went through several rounds with variations and all of
them caused the program to exit immediately.

Here is the (short) setmem I've been using:

int
setmem (addr, size, val)	/* fill, starting at addr, for size, with val */
char   *addr;
unsigned int    size;
char    val;
{
    while (size--)
	*addr++ = val;
}

I really would like to see a generic (castable) setmem...

Thanks for your patience.

--Frank
-------
18-Aug-86 19:42:55-PDT,618;000000000001
Mail-From: KLH created at 18-Aug-86 19:42:53
Date: Mon 18 Aug 86 19:42:52-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Misunderstanding?
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

OK, just ensure that all calls to setmem have the 1st argument cast to
(char *).  Not clear from your message if this is what you tried.  At
any rate something will break unless you change "setmem(htab, ...)" to
"setmem((char *)htab, ...)", likewise for any other calls to setmem.
-------
18-Aug-86 20:12:42-PDT,1193;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 18 Aug 86 20:12:39-PDT
Date: Mon 18 Aug 86 21:11:44-MDT
From: Frank J. Wancho <[email protected]>
Subject: Re: Misunderstanding?
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Ken,

I just tried your suggested (char *) cast and now it seemed to be in a
loop processing the first file.  Note that I "invented" the setmem I'm
using.  It apparently comes with the CI C/86 runtime library for
MSDOS.  Given that the other setmem calls using strtab do an explicit
(char *) in the original, and not for htab, I'm beginning to wonder
what the *real* setmem looks like.

Someone else took a mostly-bug-free stab at converting this same package
for bsd4.2 environments, and his setmem looks like this, with no cast
of (char *)htab in the calls to it.

char *setmem(dest,size,c)
char *dest,c;
int size;
{
 int i;

    for(i = 0; i < size; dest[i] = c, i++);
    return(&dest[0]);
}

How's this any different from the one I invented?

--Frank
-------
18-Aug-86 21:19:55-PDT,502;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 18 Aug 86 21:19:52-PDT
Date: Mon 18 Aug 86 22:19:00-MDT
From: Frank J. Wancho <[email protected]>
Subject: Comment char in literals inside #asm
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

The compiler is prematurely stripping the remainder of a line
when the comment character appears inside a literal on that
line.

--Frank
-------
19-Aug-86 01:47:09-PDT,1072;000000000001
Mail-From: KLH created at 19-Aug-86 01:47:03
Date: Tue 19 Aug 86 01:47:03-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Misunderstanding?
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

No different, except of course for the return value.  You can get away
with that sort of trick on the VAX and other byte-addressed machines, since
a (char *) and (int *) are the same thing.  But this is not portable to
other machines like the PDP-10, which is precisely why it is such a bad
practice to have type mismatches between a function's defined parameters
and the arguments actually given to calls.  Perhaps you should (tediously)
verify that all functions which have any kind of pointer as a parameter
are always given that exact pointer type as argument.  Also, any function
returning anything that is not of type (int) should always be declared
before it is invoked.  That is the only thing I can think of to suggest.
-------
19-Aug-86 01:50:36-PDT,513;000000000001
Mail-From: KLH created at 19-Aug-86 01:50:32
Date: Tue 19 Aug 86 01:50:32-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Comment char in literals inside #asm
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

I could guess at what you mean, but I'd rather have a specific example.
#asm will probably be redone soon, by the way, so don't use it more than
you have to.
-------
19-Aug-86 01:56:04-PDT,585;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Tue 19 Aug 86 01:56:00-PDT
Date: Tue 19 Aug 86 02:55:04-MDT
From: Frank J. Wancho <[email protected]>
Subject: Re: Comment char in literals inside #asm
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

From original .C:

	MOVE T2,[POINT 7,[ASCIZ \.-1;P770000\]] ;Want to tie off string

From generated .MAC:

	MOVE T2,[POINT 7,[ASCIZ \.-1

--Frank
-------
19-Aug-86 02:03:25-PDT,564;000000000001
Mail-From: KLH created at 19-Aug-86 02:03:20
Date: Tue 19 Aug 86 02:03:20-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Comment char in literals inside #asm
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Aha.  Yes, that is one of the problems.  Either use -C to "keep comments",
or change the delimiters to " (double-quote) instead of \.
This overly helpful trimming will probably be flushed in the next version.
-------
19-Aug-86 09:10:56-PDT,437;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Tue 19 Aug 86 09:10:53-PDT
Date: Tue 19 Aug 86 10:09:52-MDT
From: Frank J. Wancho <[email protected]>
Subject: access() for read "fails"
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

Try to access(non-existent-file, 04) and get success instead
of failure...

--Frank
-------
19-Aug-86 10:49:08-PDT,920;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Tue 19 Aug 86 10:49:01-PDT
Date: Tue 19 Aug 86 11:47:55-MDT
From: Frank J. Wancho <[email protected]>
Subject: Cancel mail utility request
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

I wrote a simple-minded envelope that reads an input file
and sets up the args to call SNDMAI, which has been coerced
into a C function.  It does no validation of the args and
is limited to processing only the first 60,000 chars of the
message body.  Sources available on request.

I now also have a working file request daemon, which I run
as a periodic batch program.  It is not-so-simple, and not
idiot-proof (yet).  Sources available for beta test.  It does
not yet split the file to be sent into chunks because fseek
is broken at the moment.

--Frank
-------
19-Aug-86 12:40:44-PDT,348;000000000001
Mail-From: IAN created at 19-Aug-86 12:40:39
Date: Tue 19 Aug 86 12:40:38-PDT
From: Ian Macky <[email protected]>
Subject: Re: access() for read "fails"
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Fixed in the latest.

--ian
-------
19-Aug-86 17:28:10-PDT,533;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Tue 19 Aug 86 17:28:01-PDT
Date: Tue 19 Aug 86 18:26:54-MDT
From: Frank J. Wancho <[email protected]>
Subject: system("string") fails
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

system("command-line-string") seems to be ignored, whereas
system(string-ptr) works.  There is no error message given
in the former case.  Should system() be declared, or ?

--Frank
-------
21-Aug-86 14:34:51-PDT,606;000000000001
Mail-From: KLH created at 21-Aug-86 14:34:44
Date: Thu 21 Aug 86 14:34:44-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: system("string") fails
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

I found a generic problem (an underlying unix-simulation routine had
changed its return value semantics) which was affecting system(), although
I doubt it has anything to do with whether you are giving it a literal
or a string pointer.
I believe it is now fixed.
-------
21-Aug-86 20:18:51-PDT,484;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Thu 21 Aug 86 20:18:36-PDT
Date: Thu 21 Aug 86 21:18:26-MDT
From: Frank J. Wancho <[email protected]>
Subject: Library contributions?
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

I have a few useful functions I've been building up
in the last month or so.  Do you want them for a
"userlib" or whatever?

--Frank
-------
21-Aug-86 20:51:24-PDT,382;000000000001
Mail-From: KLH created at 21-Aug-86 20:51:19
Date: Thu 21 Aug 86 20:51:19-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Bug-KCC
To: Relph%[email protected], [email protected]
cc: [email protected], [email protected]
In-Reply-To: <12232676744.40.RELPH@IC2060>
Message-ID: <[email protected]>

OK, you're now on BUG-KCC.
-------
21-Aug-86 20:58:17-PDT,655;000000000001
Mail-From: KLH created at 21-Aug-86 20:58:13
Date: Thu 21 Aug 86 20:58:12-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Library contributions?
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Yes, but I would want to put them in a separate library, and to do this
well requires some improvements in the LINK invocation (which I now know
how to do, and have in the works).  For the moment why don't you send me
(separately) a short description of the functions and I'll have a better
idea where they fit.
-------
22-Aug-86 14:40:41-PDT,604;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Fri 22 Aug 86 14:40:33-PDT
Date: Fri 22 Aug 86 15:40:04-MDT
From: Frank J. Wancho <[email protected]>
Subject: Strange system() bug
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

Copy some handy executable to the name CRC.EXE.  Then run
a short program to invoke it with system().  Something
will complain: "?Cannot continue".  I ended up making a
copy of the real CRC.EXE here to another name and the
program ran fine...

--Frank
-------
24-Aug-86 09:49:53-PDT,788;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sun 24 Aug 86 09:49:50-PDT
Date: Sun 24 Aug 86 10:49:32-MDT
From: Frank J. Wancho <[email protected]>
Subject: Problem with CONDCC
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

I have another library of 38 source files I'd like to maintain
with CONDCC.  However, following the same technique you use
to maintain your sources, feeding CONDCC an indirect file,
CONDCC aborts with the error message: free(): tried to free
an invalid block.  Since there is no explicit use of free()
in the program, perhaps realloc() still has problems?  I am
using CONDCC recompiled and linked with the current CLIB.REL...

--Frank
-------
24-Aug-86 14:49:26-PDT,476;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sun 24 Aug 86 14:49:23-PDT
Date: Sun 24 Aug 86 15:47:32-MDT
From: Frank J. Wancho <[email protected]>
Subject: C Mode for EMACS?
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

In my EMACS: we have both C.EMACS and CMODE.EMACS, each
different than the other.  Are they mergable?  Are there
others?

--Frank
-------
25-Aug-86 23:11:03-PDT,1238;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 25 Aug 86 23:10:57-PDT
Date: Tue 26 Aug 86 00:10:53-MDT
From: Frank J. Wancho <[email protected]>
Subject: setmem() mystery solved!
To: [email protected]
Message-ID: <[email protected]>

When I eventually get it through my head that chars are 9-bit
on this system, at least as far as KCC is concerned, most of
my troubles will be over...

The line was  setmem (htab, HSIZE * sizeof (long), 0xff), and
setmem() was using character pointers to set the values of a
long (actually int).  See the problem?  In the 32-bit, 8-bit
character world, the expected contents would have been -1
for the htab array, except here!!  The fix is to set the value
to 0x1ff... yech...  If it weren't for the (mythical) possibility
of handling 36-bit words, you could have an exact mapping to
the 32-bit world, including mixed structs, and sizeof struct
would also work, not to mention fread/fwriting structs...

I note the doc file mentions the -c7 option.  How about a
compatibility mode of -c8?  I think we could then be "portable"
in both directions!  Of course that would mean a CLIB8.REL...

--Frank
-------
26-Aug-86 00:33:46-PDT,1246;000000000001
Mail-From: KLH created at 26-Aug-86 00:33:38
Date: Tue 26 Aug 86 00:33:38-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: setmem() mystery solved!
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Congratulations!  However, the problem is that the programmer made
an explicit assumption that there were only 8 bits in a char.  It would
have been better to use the constant (~0) than the constant (0xff).

There isn't any way that using 8-bit bytes would have helped you in
that example, unless it was declared and used only as a char array.
If the intent was to set all the bits to 1 then the lower 4 bits of each
word would have contained garbage.

The -x=ch7 option is provided as a temporary crutch for programs which
need to do heavy ASCIZ stuff and which are therefore not portable anyway.
The ANSI C draft permits any size 8 bits or larger, as long as it divides
evenly into the basic units of memory.  Thus for 36 bits, char sizes of
9, 12, 18, or 36 are possible.  However, they also define various constants
so programs can easily find out what those sizes are, which will help.
-------
28-Aug-86 23:57:28-PDT,806;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Thu 28 Aug 86 23:57:24-PDT
Date: Fri 29 Aug 86 00:57:21-MDT
From: Frank J. Wancho <[email protected]>
Subject: fopen(f, "a") bug
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

If a file is opened with fopen (f, "a") and the file did
not previously exist, if the file is closed without any
form of write to it, the file is left 0(0).  A subsequent
fopen of the same form opens the file with bytesize 36.

The conditional in open() does not take into account that
a bytesize of 0 is possible and the assumption should be
the same as if the file did not previously exist - i.e.,
open the file with an assumed bytesize of 7.

--Frank
-------
 4-Sep-86 14:51:02-PDT,559;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Thu 4 Sep 86 14:50:59-PDT
Date: Thu 4 Sep 86 15:51:09-MDT
From: Frank J. Wancho <[email protected]>
Subject: (Implicit) exit() and buffered output
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

I *thought* that either an implicit or explicit exit()
would flush and pending I/O and (f)close() any open
files, especially those open for write/append.  Alas,
such is not the case...

--Frank
-------
 4-Sep-86 15:02:14-PDT,540;000000000001
Mail-From: KLH created at  4-Sep-86 15:02:08
Date: Thu 4 Sep 86 15:02:07-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: (Implicit) exit() and buffered output
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

You're right, everything is set up to call the cleanup routine, but
the STDIO cleanup routine only closes stdin, stdout, stderr.  I guess
someone took a shortcut here.  Will get fixed.
-------
 8-Sep-86 18:12:32-PDT,2026;000000000001
Return-Path: <[email protected]>
Received: from SUMEX-AIM.ARPA by SRI-NIC.ARPA with TCP; Mon 8 Sep 86 18:12:13-PDT
Date: Mon 8 Sep 86 17:04:29-PDT
From: Mark Crispin <[email protected]>
Subject: [Stu Grossman <[email protected]>: [Jean-Pierre Dautricourt <Dautricourt%[email protected]>: cfree]]
To: [email protected]
Postal-Address: 1802 Hackett Ave.; Mountain View, CA  94043-4431
Phone: +1 (415) 968-1052
Message-ID: <[email protected]>

Return-Path: <[email protected]>
Received: from Sierra.Stanford.EDU by SUMEX-AIM.ARPA with TCP; Mon 8 Sep 86 16:49:21-PDT
Date: Mon 8 Sep 86 16:49:15-PDT
From: Stu Grossman <[email protected]>
Subject: [Jean-Pierre Dautricourt <Dautricourt%[email protected]>: cfree]
To: [email protected]
Message-ID: <[email protected]>

Why did I get this message?

Even if I the message was delivered properly, I'm not the one he should
complain to.  He should send his bugs to [email protected].

			Stu
                ---------------

Return-Path: <@SUMEX-AIM.ARPA:DAUTRICOURT@BIONET>
Received: from SUMEX-AIM.ARPA by Sierra.Stanford.EDU with TCP; Mon 8 Sep 86 16:35:46-PDT
Received: from BIONET by SUMEX-AIM.ARPA with Cafard; Mon 8 Sep 86 16:32:46-PDT
Date: Mon 8 Sep 86 12:55:11-PDT
From: Jean-Pierre Dautricourt <Dautricourt%[email protected]>
Subject: cfree
To: bug-kcc%[email protected]
Message-ID: <12237361641.30.DAUTRICOURT@IC2060>

We transfered a new version of KCC yesterday.  The following program:

#include <stdio.h>

main()
{
 int *arr;

 if ((arr=(int *)calloc(1000,sizeof(int)))== NULL) {
  printf(" cannot allocate array\n");
  exit();
  }

 cfree(arr);
 exit();
}


returns the message: free(): tried to free invalid block.

Subsequent starts of the program work, however.  But somthing is wrong the 
first time.  

Jean-Pierre Dautricourt
-------
-------
-------
 9-Sep-86 15:16:14-PDT,2468;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Tue 9 Sep 86 15:15:51-PDT
Date: Tue 9 Sep 86 16:06:27-MDT
From: Frank J. Wancho <[email protected]>
Subject: Current Status?
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

Well?  Is it almost ready to unleash on the world?

I haven't uncovered any new bugs lately, but then the program seems to
have stablized too.  I was going to ask for another runtime
capability.  But, if you're close to release, I'll go rewrite the NMIT
version (of the COMND% JSYS interface, which it seems I'll be needing
soon).

General comments:

1.  Please provide "man"-type pages for all the internal functions.
It is not necessary to document all the standard runtime functions.  A
good skeleton to start with is the NMIT version from here in
<C-DOCUMENTATION>CL-USER.DOC.  Perhaps the TOPS-20-unique functions
should be in their own (set of) REL file(s) instead of spread out here
and there?  As I am not familiar with how the linker works, I suspect
that it includes an entire rel module, even though it may contain
functions which aren't called.  Does the compiler try to set things up
so that each function appears in a rel as if it was grouped by MAKLIB
and thus separately extractable?

2.  I haven't commented on the compiler before, but, while I'm at
it...  The compiler seems easily confused by dumb errors and doesn't
try to make assumptions (with a warning) so that it can get back in
sync again.  For example, if you forget a trailing double-quote in a
string or a trailing semicolon in a statement, the volume of errors
generated from the misinterpretation of subsequent and otherwise valid
statements is astounding!  I haven't reported any of those cases
because they were trivial to recognize and fix after stopping the
compile with a handful of ^Cs - just don't ever do a compile in
batch...

There are several cases, probably already known to you, where the
compiler gets stuck, reporting the same error(s) on a statement, and
never breaks out.  Again, it's a case where it should have announced
it was making an assumption and then pressed on.  I suppose I should
have tried to reduce the code to a reproducable case the times it
occurred and sent it on.  But, again the fix was obvious, and it
didn't seem important enough to report as I was in a hurry.

--Frank
-------
 9-Sep-86 17:57:32-PDT,1079;000000000001
Return-Path: <@SUMEX-AIM.ARPA:DAUTRICOURT@BIONET>
Received: from SUMEX-AIM.ARPA by SRI-NIC.ARPA with TCP; Tue 9 Sep 86 17:57:26-PDT
Received: from BIONET by SUMEX-AIM.ARPA with Cafard; Tue 9 Sep 86 17:55:49-PDT
Date: Tue 9 Sep 86 12:10:27-PDT
From: Jean-Pierre Dautricourt <Dautricourt%[email protected]>
Subject: cfree
To: [email protected]
Message-ID: <12237615642.36.DAUTRICOURT@IC2060>

 8-Sep-86 12:55:11-PDT,623;000000000001
Date: Mon 8 Sep 86 12:55:11-PDT
From: Jean-Pierre Dautricourt <Dautricourt@IC2060>
Subject: cfree
To: bug-kcc@IC2060
Message-ID: <12237361641.30.DAUTRICOURT@IC2060>

We transfered a new version of KCC yesterday.  The following program:

#include <stdio.h>

main()
{
 int *arr;

 if ((arr=(int *)calloc(1000,sizeof(int)))== NULL) {
  printf(" cannot allocate array\n");
  exit();
  }

 cfree(arr);
 exit();
}


returns the message: free(): tried to free invalid block.

Subsequent starts of the program work, however.  But somthing is wrong the 
first time.  

Jean-Pierre Dautricourt
-------
 9-Sep-86 20:00:41-PDT,4694;000000000001
Mail-From: KLH created at  9-Sep-86 20:00:37
Date: Tue 9 Sep 86 20:00:36-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Current Status?
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

I don't know about unleashing, but the next major version is just
about ready, and I'll consider that to be a release when it happens.

There will be a number of things different about this KCC.  The main
one is that the extended-addressing decision will be made at load time
rather than at run time; this requires recompilation of everything you
have.  The library is now called LIBC, not CLIB.  The linking loader
is invoked somewhat differently; TMPCOR files are supported, and the
trend is towards using KCC as an interface to LINK much as UNIX "cc"
is an interface to "ld".  An asm() expression is supported within
functions (and replaces #asm).  Identifier quoting is possible, so
symbols like %$.FOO can be referenced within C.  STDIO should support
update mode and a few of the ANSI draft suggestions.  Etc...

I've also been busy putting a code version number in everything that
KCC generates so that any attempt to load modules generated by
too-different KCCs will cause the loader to complain.  This is with
an eye to future changes in the generated code, and will make it
less risky to introduce such changes.

Some comments on your comments:

>1.  Please provide "man"-type pages for all the internal functions.
	Internal functions?  So far the only really specific one is jsys().
	There are a couple that exist mainly for KCC.
	All others are standard runtimes of one sort or another.

>It is not necessary to document all the standard runtime functions.  A
>good skeleton to start with is the NMIT version from here in
><C-DOCUMENTATION>CL-USER.DOC.
	We'll need to pursue this someday, certainly, as new stuff
	begins to appear.
>				  Perhaps the TOPS-20-unique functions
>should be in their own (set of) REL file(s) instead of spread out here
>and there?  As I am not familiar with how the linker works, I suspect
>that it includes an entire rel module, even though it may contain
>functions which aren't called.  Does the compiler try to set things up
>so that each function appears in a rel as if it was grouped by MAKLIB
>and thus separately extractable?
	No, when a .REL module is loaded, you get the whole thing.
	UNIX works this way too, and in fact it is extremely difficult
	to see how it could possibly work otherwise.
	So it really depends on the granularity of the source files.
	Is there any specific grouping that bothers you?

>2.  I haven't commented on the compiler before, but, while I'm at
>it...  The compiler seems easily confused by dumb errors and doesn't
>try to make assumptions (with a warning) so that it can get back in
>sync again.  For example, if you forget a trailing double-quote in a
>string or a trailing semicolon in a statement, the volume of errors
>generated from the misinterpretation of subsequent and otherwise valid
>statements is astounding!  I haven't reported any of those cases
>because they were trivial to recognize and fix after stopping the
>compile with a handful of ^Cs - just don't ever do a compile in
>batch...

	Yes; however, the difference between illegal code and sloppy code
	is sometimes subtle.  The free-format nature of C makes it hard
	to find good recovery points, however.  If the start of a function
	declaration is botched, then the entire function generates a spate
	of errors because it looks like a bunch of invalid top-level
	declarations.  It is hard to know what to do about those cases.
	If anyone knows of good algorithms, let me know.

>There are several cases, probably already known to you, where the
>compiler gets stuck, reporting the same error(s) on a statement, and
>never breaks out.  Again, it's a case where it should have announced
>it was making an assumption and then pressed on.  I suppose I should
>have tried to reduce the code to a reproducable case the times it
>occurred and sent it on.  But, again the fix was obvious, and it
>didn't seem important enough to report as I was in a hurry.

	As far as I know, all such looping problems have been fixed.
	It is important to report such bugs.  For these, at least, it
	is OK to provide the entire source file (run it through -E first)
	because it's easy to single-step once it starts looping.  It's
	mainly for over-optimization bugs that a most-simple test case is
	essential.

Send in more comments as they come to mind...
-------
10-Sep-86 11:50:02-PDT,696;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Wed 10 Sep 86 11:49:57-PDT
Date: Wed 10 Sep 86 12:48:55-MDT
From: Frank J. Wancho <[email protected]>
Subject: Re: Current Status?
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Ken,

The "internal" functions I have in mind are those which
have a leading underscore, such as _gtjfn, _gtfdb, _rljfn,
which can be considered as canned interfaces to those JSYS'.
Others are of the utility catagory, such as file_parse to
name one that comes to mind.

--Frank
-------
10-Sep-86 16:47:36-PDT,682;000000000001
Return-Path: <@SUMEX-AIM.ARPA:DAUTRICOURT@BIONET>
Received: from SUMEX-AIM.ARPA by SRI-NIC.ARPA with TCP; Wed 10 Sep 86 16:47:18-PDT
Received: from BIONET by SUMEX-AIM.ARPA with Cafard; Wed 10 Sep 86 16:44:56-PDT
Date: Wed 10 Sep 86 14:23:51-PDT
From: Jean-Pierre Dautricourt <Dautricourt%[email protected]>
Subject: bug: characters entered as escape characters.
To: [email protected]
Message-ID: <12237902071.51.DAUTRICOURT@IC2060>


Character constants entered as escape characters: the second open
quote is not parsed.  E.g.:

	putc('\35',fp);

will give error: 

 	Wrong number of args - 2 expected, 1 seen


Jean-Pierre Dautricourt
-------
10-Sep-86 17:21:46-PDT,546;000000000001
Mail-From: KLH created at 10-Sep-86 17:18:46
Date: Wed 10 Sep 86 17:18:46-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: bug: characters entered as escape characters.
To: Dautricourt%[email protected], [email protected]
cc: [email protected]
In-Reply-To: <12237902071.51.DAUTRICOURT@IC2060>
Message-ID: <[email protected]>

This was a problem with macro arg parsing; now fixed.  Thanks...
I would not advise getting a new KCC just now, though, since we are
about to install another new regime.
-------
10-Sep-86 19:42:02-PDT,569;000000000001
Return-Path: <[email protected]>
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Wed 10 Sep 86 19:41:57-PDT
Date: Wed 10 Sep 86 20:41:33-MDT
From: Frank J. Wancho <[email protected]>
Subject: open fails on quoted filenames
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

file_parse in open.c incorrectly handles quoted filesnames.
For example PD:<SIGM.VOL100>SIG^V/M.LIB becomes PD:<SIGM.VOL100.SIG>M.LIB
which doesn't exist and the fopen which calls that sequence fails.

--Frank
-------
11-Sep-86 03:01:24-PDT,1060;000000000001
Mail-From: KLH created at 11-Sep-86 03:01:18
Date: Thu 11 Sep 86 03:01:17-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: cfree
To: Dautricourt%[email protected], [email protected]
cc: [email protected]
In-Reply-To: <12237615642.36.DAUTRICOURT@IC2060>
Message-ID: <[email protected]>

The reason your program doesn't work is because you are not giving the
correct type of argument to cfree().  The argument must be of type (char *),
not (int *).  It is very important with KCC to keep your types consistent,
because a (char *) is much different from a (int *); the former is a byte
pointer, the latter is a word address.  If you used the call
	cfree((char *)arr);
then it should work.

In theory there is really nothing the compiler can do to ensure that you
are giving the right types of arguments to a function; this has always
been a weak point of C which the ANSI draft is trying to fix.  At least
our memory allocation routines try to be careful, and the checking
worked properly in this case.
-------
11-Sep-86 17:03:18-PDT,417;000000000001
Mail-From: IAN created at 11-Sep-86 16:57:53
Date: Thu 11 Sep 86 16:57:49-PDT
From: Ian Macky <[email protected]>
Subject: Re: open fails on quoted filenames
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

ok, ^V quoting is fixed in the latest version of file_parse(), to be
released soon.

--ian
-------
11-Sep-86 20:03:11-PDT,791;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Thu 11 Sep 86 19:26:40-PDT
Date: Thu 11 Sep 86 20:26:09-MDT
From: Frank J. Wancho <[email protected]>
Subject: Re: open fails on quoted filenames
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Ian,

I have since had a chance to look more closely at file_parse() and
there may be TWO problems, one of which might be the ^V quoting.  But,
I think that's a red herring...

The "real" problem is that the parse does not stop after a ">" is
seen.  (In fact, it should be testing for either form of "<>" or "[]"
pairs.)  The function is actually misnamed - it should be dir_parse().

--Frank
-------
23-Sep-86 18:15:40-PDT,690;000000000001
Received: from SUMEX-AIM.ARPA by SRI-NIC.ARPA with TCP; Tue 23 Sep 86 17:23:31-PDT
Received: from BIONET by SUMEX-AIM.ARPA with Cafard; Tue 23 Sep 86 17:19:06-PDT
Date: Mon 22 Sep 86 14:07:34-PDT
From: Jean-Pierre Dautricourt <Dautricourt%[email protected]>
Subject: bug in gets?
To: [email protected]
cc: will%[email protected]
Message-ID: <12241044833.28.DAUTRICOURT@IC2060>


The following program:

main()
{
char command[100];

do {
 printf("\ntype something: ");
 *command = '\0';
 printf("that was:%s",gets(command));
 } while(1);
}

works fine except if you happen to type Ctrl-Z it keeps looping forever...

Jean-Pierre
-------
23-Sep-86 19:15:40-PDT,444;000000000001
Mail-From: KLH created at 23-Sep-86 19:10:51
Date: Tue 23 Sep 86 19:10:48-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: bug in gets?
To: Dautricourt%[email protected], [email protected]
cc: will%[email protected], [email protected]
In-Reply-To: <12241044833.28.DAUTRICOURT@IC2060>
Message-ID: <[email protected]>

It's supposed to.  Ctrl-Z is EOF for TTY input, just as Ctrl-D is on UNIX.
-------
24-Sep-86 23:15:41-PDT,1490;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Wed 24 Sep 86 23:11:01-PDT
Date: Thu 25 Sep 86 00:09:27-MDT
From: Frank J. Wancho <[email protected]>
Subject: fclose() bug?
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

In a program with several files already fopen'd, some for read,
some for write, an attempt is made to fopen a non-existent file.
Unfortunately, a coding error caused an fclose() to be done with
an fd of that file that didn't exist.  (I should also mention that
in the process of running the program, several files have been
opened and closed at various times, including several successful
passes through this same function that now failed.)

This fclose() must have really gone astray because the batch log
file showed output which should have gone to files all mixed with
stderr output.

My point is that I suspect that fclose() does not seem to be idiot-
proof and (this is a guess) trashes the fd list with spectactular
results.  (BTW, I should also mention that this batch job runs
under OPERATOR, and there is also trash output to the system
console at the same time as trash appears in the batch log, although
not always.  It seems to be dependent on how the fd list got
trashed.)

I wish I could supply a better analysis of the situation to help
pinpoint the problem more accurately.  Of course I will be fixing
the coding error in the meantime...

--Frank
-------
28-Sep-86 03:28:09-PDT,3800;000000000001
Mail-From: KLH created at 28-Sep-86 03:01:53
Date: Sun 28 Sep 86 03:01:52-PDT
From: Ken Harrenstien <[email protected]>
Subject: New KCC distrib snapshot
To: [email protected]
Message-ID: <[email protected]>

	A new snapshot of KCC sources is ready.  I'm sending this
initially to BUG-KCC instead of INFO-KCC so that if there are any
immediately obvious (or embarrassing) problems they will only affect a
few people instead of everybody.  To retrieve the files, use anonymous
FTP to SRI-NIC.ARPA and FTP everything in the directory that the
logical name KCCDIST: points to.  Note there are several subdirectories.
	Here is a summary of the new stuff, extracted from NEWS.TXT:
-----------------------------------------------------------------------
09/28/86 KCC 533, LIBC 14: <1,,1>	Second formal distribution snapshot

	This is called a "snapshot" to emphasize that while the sources
in this distribution should be consistent and working, the compiler and
library are still under active development to remove known quirks and
deficiencies, and have already changed.
	As before, all .REL files must be recompiled; the STDIO
structures are different and there are new C runtime hooks.  Most
importantly, the symbol $$CVER is now defined in every module
(currently it is <1,,1>) so as to detect any future conflicts when
loading modules that were incompatibly compiled.
	Various change notes follow.  For all of them, see the CC.DOC
file for more details.

KCC: ---------------------------------------------------------------

KCC - Command line
	There are several new switches, and the way KCC interprets
filenames is slightly different.  A file with a .REL extension is
always ignored, but is passed on to the loader.  A file without any
extension is special if the -q switch is given; it is only compiled if
the .C source is more recent than the .REL binary.
	New switches:
	-A	Specify nonstandard assembler header file (old meaning of -H)
	-H	Specify nonstandard path for #include <> files.
	-i	Loader: load program to run with extended addressing.
	-L	Loader: nonstandard path for library files.
	-l	Loader: search specified library
	-o	Loader: specify .EXE filename.
	-P	Set portability level.
	-q	Compile extension-less files conditionally.

KCC - General
	There are no real changes in code generation.  A couple of
over-optimization bugs were fixed, and a couple of other optimizations
added.
	KCC now generates its own assembler header based on the target
CPU, assembler, and system; the file C-HDR.FAI no longer exists.
	Two more KCC extensions were added: the `ident` quoting syntax,
and the asm() in-line code mechanism.  #asm and #endasm must now appear
only within a function body.
	KCC identifiers are now unique up to 31 characters, as per the
ANSI draft (external symbols are still only unique up to 6).
	The runtime variable $EXADF no longer exists.  The decision on
whether to run extended is now made at load time, either with the -i switch
or by loading C:LIBCKX as the first module.

LIBC: --------------------------------------------------------------

LIBC - CHAR
	ispunct() was "fixed" to exclude space.  CARM claims space is
included, but neither ANSI nor BSD does so.  We assume this is a mistake
in CARM.

LIBC - STRING
	The routines memchr, memcmp, memcpy, memset were added from ANSI.

LIBC - STORAGE
	free(), malloc(), and realloc() now behave as per ANSI when given
NULL or zero as arguments.

LIBC - STDIO
	The "update" mode is now supported for streams.  In addition
to this, the library implements the ANSI concept of text vs binary
streams.  The 'R' specification was flushed; 'b', '7', '8', '9', 'C',
and "C-" were added.

LIBC - other
	system() was added.
-------
30-Sep-86 14:45:32-PDT,947;000000000001
Received: from SUMEX-AIM.ARPA by SRI-NIC.ARPA with TCP; Tue 30 Sep 86 14:16:27-PDT
Received: from BIONET by SUMEX-AIM.ARPA with Cafard; Tue 30 Sep 86 14:11:29-PDT
Date: Tue 30 Sep 86 14:00:40-PDT
From: Will Rusch <WILL%[email protected]>
Subject: stack overflow
To: [email protected]
Message-ID: <12243140729.36.WILL@IC2060>

I'm having a difficult-to-describe problem.  The stack overflows at
locations like/near FFLUSH, FPUTC, ... immediately before my program
dies.

By inserting a random sprintf statement with more than three arguments,
like sprintf(str,"%s%s","die","bat") the symptoms disappear.  I
suspect the compiler is the problem because of this intermittent
failure.  But, I'm not convinced that my program isn't clobbering
the call stack.

Has anyone had similar problems?

					Will

Ps.  gets(s) does not write an empty string into s when the
only a Return is typed at the keyboard.
-------
30-Sep-86 15:46:10-PDT,707;000000000001
Mail-From: KLH created at 30-Sep-86 15:09:53
Date: Tue 30 Sep 86 15:09:50-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: stack overflow
To: WILL%[email protected], [email protected]
cc: [email protected]
In-Reply-To: <12243140729.36.WILL@IC2060>
Message-ID: <[email protected]>

Well, what DOES the stack pointer look like?  I've never heard of this
kind of problem, and without more information it's difficult to even think
of anything to suggest.  You need to do more debugging.

See if you can get the latest KCC and LIBC.  You didn't say what version you
had, but the current gets() is known to work, which makes me think the
one you have is old.
-------
 2-Oct-86 00:38:22-PDT,388;000000000001
Received: from Sierra.Stanford.EDU by SRI-NIC.ARPA with TCP; Thu 2 Oct 86 00:01:04-PDT
Date: Thu 2 Oct 86 00:01:56-PDT
From: Stu Grossman <[email protected]>
Subject: overly protected file
To: [email protected]
Message-ID: <[email protected]>

I can't read the file  SS:<KCCDIST.LIB>GETOPT.C.  It's too highly protected.

			Stu
-------
 2-Oct-86 02:37:57-PDT,427;000000000001
Mail-From: KLH created at  2-Oct-86 01:56:15
Date: Thu 2 Oct 86 01:56:10-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: overly protected file
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Sigh. I found some other dubious protections and fixed those as well. Thanks.
-------
 3-Oct-86 10:39:51-PDT,1086;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Fri 3 Oct 86 10:26:29-PDT
Date: Fri, 3 Oct 1986  11:26 MDT
Message-ID: <[email protected]>
From: [email protected]
To:   [email protected]
cc:   [email protected]
Subject: A couple of requests

1.  Any strong reason for making log_expand() static in OPEN.C?  I use
the function and was surprised to find it hidden.

2.  For compatibility, users and programs should not be concerned
about quoting special characters in TOPS-20 filenames.  I propose that
filename strings be handled internally by the runtime system along the
same lines I'm using now: "dequote" the string and then "enquote" it
before passing it along.  (My enquote calls dequote before actually
enquoting the string.  Do you want it?)

3.  The command line option to allow library searches by the loader is
welcome, but awkward when the library name does not start with "LIB".
Is there any clean way a REQUEST statement can be inserted in the
source for the main function without generating conflicts?

--Frank
 3-Oct-86 12:37:57-PDT,2729;000000000001
Mail-From: KLH created at  3-Oct-86 12:19:14
Date: Fri 3 Oct 86 12:19:08-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: A couple of requests
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

	1.  Any strong reason for making log_expand() static in OPEN.C?  I use
	the function and was surprised to find it hidden.

Yes.  In general the only externally visible symbols provided by the
runtime library should be those which are specifically intended for external
use, and which are documented to exist.  Exception: definitions which need
to be accessed by several modules of a package, although still not intended
for package-external use; these should all begin with "_".
log_expand() is internal to OPEN.C.  If you think it is truly that useful
you could make it part of a TOPS-20 specific library, but personally
I don't think it represents the right approach to the subdirectory problem.

	2.  For compatibility, users and programs should not be concerned
	about quoting special characters in TOPS-20 filenames.  I propose that
	filename strings be handled internally by the runtime system along the
	same lines I'm using now: "dequote" the string and then "enquote" it
	before passing it along.  (My enquote calls dequote before actually
	enquoting the string.  Do you want it?)

I'm not sure I understand.  You have to have some quoting mechanism all
the way down and this isn't compatible with anything else.  Anything that
scans a TOPS-20/TENEX filename should realize that ^V quotes ANYTHING
(not sure about NUL though).  Without this understanding you are limited
to vanilla filenames without special characters.  There is no way to "add"
these quotes once they have been removed, so they can never be removed.

	3.  The command line option to allow library searches by the loader is
	welcome, but awkward when the library name does not start with "LIB".
	Is there any clean way a REQUEST statement can be inserted in the
	source for the main function without generating conflicts?

No, the -l switch works by passing the library filename to the loader, not
by inserting a .REQUEST in the assembler file.  Thus it does not do anything
at all if KCC is not invoking LINK itself.  KCC does still stick in a
.REQUEST for the runtime library, mainly for compatibility with the way
previous versions worked.  You can ask for arbitrary library filenames
by just giving the .REL filename; KCC passes them along unchanged.
More complicated ways of doing things are easier done with .MIC or .CMD
files, or something equivalent to UNix "make".
-------
 6-Oct-86 22:37:24-PDT,938;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 6 Oct 86 21:38:50-PDT
Date: Mon 6 Oct 86 22:38:58-MDT
From: Frank J. Wancho <[email protected]>
Subject: system() broken?
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

I cannot pinpoint the cause, but it appears that system() is broken.
The symptoms are "?Cannot continue" messages when system() is invoked
(and the action is performed only the first time).  This was with the
same source as the production executable.

With a later version of the source, I inserted fprintf's to stderr to
display the argument string to system().  Only the first string was
displayed when several were expected, one for each system() call.

Somehing peculiar is going on and I can't seem to reproduce the
problem in a small test case.  However, the real program repeatedly
reproduces the problem.

--Frank
-------
 6-Oct-86 23:37:26-PDT,2495;000000000001
Mail-From: KLH created at  6-Oct-86 23:31:21
Date: Mon 6 Oct 86 23:31:17-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: system() broken?
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

OK, I think I know what's going on.  system() is doing a vfork() to create the
inferior fork, and then an exec() to load up the requested program.  The
problem is that certain timing considerations led the authors of the
original vfork/exec code to rely on a HALTF% synchronization mechanism; the
superior waits until the inferior has haltf'd once, and then knows it is
OK to continue its own processing as well as that of the inferior because
the page mapping has been set up properly by that time.

What is happening is that the exec() fails, almost certainly because it could
not access the given program filename, and thus it never gets to the
part where it signals the superior that it's OK to go on.  So instead of
the inferior's hitting HALTF% inside the exec() call, it hits the HALTF%
inside _exit() which terminates the inferior.  The superior (still in
vfork()) thinks "aha, the inferior has set up its page map and is ready
to go, it's time to continue myself (and continue the inferior too)".  So
when the inferior is continued, the _exit() code quite reasonably complains
"Cannot continue".

Meanwhile, because the inferior's _exit() happened while they were still
sharing the SAME address space, all of the STDIO buffers, flags, and open
file channels have been flushed.  No wonder the superior has no way to
communicate with the outside world from that point.

The straightforward solution is to replace vfork() with fork() in the
system.c source.  But this is painfully slow, which is why vfork() was
invented by BSD.  I don't know right now how BSD solves the problem of
having a child process terminate while still sharing the same page map
as its parent process.  Hmmm.  As a quick patch, insert this code
into your version of system.c right between the exec() call and the
_exit() call:

#if SYS_T20+SYS_10X
	asm("SEARCH MONSYM\n HALTF%\n JRST .-1\n");
#endif

This simply causes the system() call to do nothing if the exec() fails.
Doesn't tell you why it fails, of course, but at least it doesn't trash
the program either.

I will need to think about this some more to figure out a better
solution.
-------
 7-Oct-86 08:23:51-PDT,897;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Tue 7 Oct 86 08:12:25-PDT
Date: Tue 7 Oct 86 09:12:03-MDT
From: Frank J. Wancho <[email protected]>
Subject: Re: system() broken?
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Ken,

But, this was all working before this new release.  All I thought
you changed is the addition of some code to guarantee the primary
I/O channels are restored (based on a quick reading).  Could that
be the real culprit?  Alternately, would you reconsider the code
I originally submitted as a possible "solution"?

I'm at DECUS and today is the big day for 10/20 sessions.  I'll
have an answer on the results of your suggested patch tomorrow
after I can get to a real terminal instead of this TI...

--Frank
-------
 8-Oct-86 03:29:32-PDT,545;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Wed 8 Oct 86 02:59:03-PDT
Date: Wed 8 Oct 86 03:59:10-MDT
From: Frank J. Wancho <[email protected]>
Subject: Re: system() broken?
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Ken,

I inserted the suggested lines into a private copy of
system.c and link complained:

FTH Fullword value WAIT being truncated to halfword

Now what?

--Frank
-------
13-Oct-86 17:20:10-PDT,902;000000000001
Received: from Sierra.Stanford.EDU by SRI-NIC.ARPA with TCP; Mon 13 Oct 86 17:12:44-PDT
Date: Mon 13 Oct 86 17:11:54-PDT
From: Stu Grossman <[email protected]>
Subject: Bug in scanf
To: [email protected]
Message-ID: <[email protected]>

Just found a bug in scanf().  The statement:

	scanf("%d",&i);

puts garbage into i when the input is preceded by a + or - sign.

The fix:
In SCANF.C, change the line that looks like (in duo_scanf()):
from:
	case '+':    if (--sf->width > 0) c = getc(sf->stream);
to:
	case '+':    if (--sf->width) c = getc(sf->stream);

There is another bug that I found while playing with this.  If you type
non-numeric stuff (like the word foo) instead of a number you get garbage
also.  In Unix, you get a 0 if it can't parse the number.  This problem is
not fixed by the aforementioned patch.

			Stu
-------
13-Oct-86 17:50:05-PDT,1205;000000000001
Mail-From: IAN created at 13-Oct-86 17:46:38
Date: Mon 13 Oct 86 17:46:37-PDT
From: Ian Macky <[email protected]>
Subject: Re: Bug in scanf
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

thanks for the scanf() bugfix - it's been incorporated into our sources.

as for the behavior of a numeric parse upon encountering text, CARM says:

    "The input operation may terminate prematurely because the
    input stream reaches end-of-file or because there is a
    conflict between the control string and a character read
    from the input stream.  The value returned by scanf is the
    number of successful ASSIGNMENTS [my caps] performed before
    termination of the operation for either reason."

i checked out the behavior with our scanf and on a 4.2BSD, and in both
cases no assignment was made (0, garbage, or otherwise) for a bogus
numeric parse of just text.  no assignment was made, and the return
value of scanf reflected that.

if you're getting different behavior than this, could you send a code
fragment that demonstrates the problem?

--ian
-------
18-Oct-86 19:51:55-PDT,1925;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sat 18 Oct 86 19:40:54-PDT
Date: Sat 18 Oct 86 20:40:40-MDT
From: Frank J. Wancho <[email protected]>
Subject: Re: system() broken?
To: [email protected]
cc: [email protected], [email protected]
Message-ID: <[email protected]>

    What is happening is that the exec() fails, almost certainly
    because it could not access the given program filename, ...

I think you're on to something: it really isn't so much a problem with
system() as it is what is being fed to it, or some other runtime
problem caused by the recent overhaul in the way things work.

To prove this point, I recompiled and relinked the source for the
current running version of the program, which is still running quite
well as far as it goes (I have a much newer version waiting in the
wings).  The program filenames used by the program are definitely do
exist.

I had also tried inserting the asm code you suggested, and reported
the linker error message, but received no reply.

Since then, I found the source to my original version of system() and
reduced the code and tested it on a single call.  It worked just fine
(and fast, too!).  When I used this version to link with the real
program, I did not get the "?Cannot continue" messages.  (Those
messages still remain a mystery.)  In fact, certain expected calls to
system() are not made at all!  (I put fprintf's in my version of
system() to display its argument.)  Those which are made are correctly
executed.

There may, in fact, be more than one bug being tickled with my
program.  At this point, I'm inclined to believe that there is a far
deeper seated problem with the environment that is well beyond by
abilities to debug.  In the meantime, I'm backtracking through all my
previous bug report test cases to see if any of those cases have
reappeared.

--Frank
-------
19-Oct-86 06:36:59-PDT,952;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sun 19 Oct 86 06:21:57-PDT
Date: Sat 18 Oct 86 18:42:20-MDT
From: Frank J. Wancho <[email protected]>
Subject: Truncation in literals
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

Ken,

cc still truncates on detecting a semicolon while inside
an #asm inside a literal as in:

	MOVE	2,[POINT 7,[ASCIZ ".-1;P770000"]]

Note the use of the suggested double-quotes instead of
the backslashes I had been using.

I also tried using the -C option, but that produced
an overflow of some sort.

I also note that the assembler input contains everything
up to the semicolon on each line.  I doubt it it's all that
much overhead for MACRO to ignore, but it would appear that
whitespace suppression is not that big a deal to implement
on-the-fly as long as comments are being stripped at the
same time...

--Frank
-------
19-Oct-86 14:22:03-PDT,634;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sun 19 Oct 86 14:17:37-PDT
Date: Sun 19 Oct 86 15:03:49-MDT
From: Frank J. Wancho <[email protected]>
Subject: DEFINEs apply inside #asm !!
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

Consider noting that if one includes JSYS.H, its #defines are applied
inside #asm statements when the jsys being called is UPPERcased.  By
my self-imposed MACRO coding conventions, I uppercase variables and
jsys references.  I just discovered that MACRO doesn't know that 023%
was meant to be RLJFN%...

--Frank
-------
19-Oct-86 20:07:07-PDT,757;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sun 19 Oct 86 19:59:35-PDT
Date: Sun 19 Oct 86 20:59:22-MDT
From: Frank J. Wancho <[email protected]>
Subject: Found it!
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

Relentlessly pressing on, I found the problem:

old form:  jfn = _uioch[f->siofd];

new (unadvertized) form:  jfn = _uioch[_uioufx[f->siofd]];

Of course, that's what I get for fooling around using
low-level code that's subject to change without notice.

So, cancel last so-called bug report where I claimed the
problem was "deep-seated".  (It was, but that's besides
the point - I also claimed it was beyond my capabilities
to find...)

--Frank
-------
22-Oct-86 22:23:04-PDT,2257;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Wed 22 Oct 86 22:11:06-PDT
Date: Wed 22 Oct 86 23:10:40-MDT
From: Frank J. Wancho <[email protected]>
Subject: Ordering library modules
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

There are two things that may be done to help improve
the performance of LINK's library searches.  The first
is to pass the file through MAKLIB's /INDEX option.  The
second is to make some attempt to order the modules so
that external references are all forward references.

That second is hard to do without computer aids.  Neil Maron
wrote just such a program in FORTRAN, and Norm Samuelson
subsequently enhanced it.  It was originally meant to be
used to help order large FORTRAN libraries, but not quite
as large as LIBC is today.

In order to get it to process LIBC.REL, I had to make several
iterative minor edits to successively increase its internal
"stack".  The results of that change now works on LIBC.REL and
produces some interesting results.  The files are here in
SS:<SOURCES.UNSUPPORTED>LIB*.*, including LIBORD.EXE.

To run LIBORD, just execute it, and give it the name of the
.REL file you want processed.  You can give it either the
list of the component .REL files, or just LIBC.REL and it
does all the work for you.  It will eventually prompt for
a listing file, and also produce a LIBORD.MIC.  That latter
file can then be used to create the newly ordered WORK.REL
by extracting each of the modules and then appending them
together in the order the program devised.

What is interesting is that LIBORD complains about possible
recursion and asks you to give the module names to "force".
I have not encountered this request before.  I suspect that
it want you to specify which modules should be on top of the
pile.  I leave that to any interested party to figure out.

I present all the above for what it may be worth to you as
a possible technique to improve the performance of the
package.  Whether you find it useful or not, please let me
know.  If you make changes in the program (or convert it to
C), I'd like the results back to keep available here for
others to use.

--Frank
-------
26-Oct-86 21:53:48-PST,1071;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sun 26 Oct 86 21:39:40-PST
Date: Sun 26 Oct 86 22:39:44-MST
From: Frank J. Wancho <[email protected]>
Subject: Bug with rewind() or ?
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

Read the following file with the short program that follows it.
The problem should be self-evident.  Please let me know what
I'm doing wrong or when you have a fix.

--Frank
----------
File to read:
Line 1
Line 2
Line 3
---------
Program to read it:
#include <stdio.h>

#define LINESIZE 1026

FILE	*f;

char	line[LINESIZE];

main (num, arg)
char	*arg[];
{
    if ((f = fopen (arg[1], "r")) == NULL) {
	fprintf (stderr, "fopen failed on %s\n", arg[1]);
	exit (1);
    }
    while (readit() != EOF);
    fprintf (stderr, "Rewinding...\n");
    rewind (f);
    while (readit() != EOF);
}

int
readit ()
{
    while ((fgets (line, LINESIZE, f)) != NULL) {
	fprintf (stderr, "%s", line);
    }
    return (EOF);
}
----------
-------
30-Oct-86 13:58:38-PST,1281;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Thu 30 Oct 86 13:49:42-PST
Date: Thu, 30 Oct 1986  16:50 EST
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: Bad generated code

This might be the fault of the weird state my compiler/library etc are
in.  Here's what I get.  Note the lack of an ADJSP at label "foo:" and
the -2(P) offset in the LDB pointer.

----------------
Source file:
----------------
struct mumble {
    unsigned a : 2;
    unsigned b;
};

foo(h)
    struct mumble *h;
{
    int c;
    if(!h->a)
	return;
}
----------------
FAIL output:
----------------
	TITLE	foo
	.REQUEST C:LIBc.REL
	$$CVER==<1,,1>
	INTERN $$CVER
	OPDEF ADJBP [IBP]
DEFINE %CHRBP(A,M)
<	SETO A,
	ADJBP A,M
>
IFNDEF ERJMP,< OPDEF ERJMP [JUMP 16,] >
OPDEF ERJMPA [ERJMP]
OPDEF	XMOVEI	[SETMI]
	DEFINE IFIW <SETZ >
	TWOSEG	400000	
	RELOC	0	
	RELOC	400000	
	DEFINE %%CODE <RELOC>
	DEFINE %%DATA <RELOC>
PURGE IFE,IFN,IFG,IFGE,IFL,IFLE,IFDEF,IFNDEF,IFIDN,IFDIF
foo:
	LDB 4,[420237,,-2]
	CAIN 4,0
	 POPJ 17,
	POPJ 17,

$$CPKI==0
	INTERN $$CPKI
$$CPKA==0
	INTERN $$CPKA

	LIT
	EXTERN	$$$CPU
	EXTERN	$$$CRT
	INTERN	foo
	END
31-Oct-86 00:43:28-PST,544;000000000001
Mail-From: KLH created at 31-Oct-86 00:41:16
Date: Fri 31 Oct 86 00:41:14-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Bad generated code
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Congratulations on finding a Real Bug.  This has been fixed as of KCC 535.

The problem was that whoever wrote the code to optimize out ADJSPs forgot
to have it check for indexing in byte-pointer literals.
-------
31-Oct-86 01:13:28-PST,466;000000000001
Mail-From: KLH created at 31-Oct-86 01:01:07
Date: Fri 31 Oct 86 01:01:02-PST
From: Ken Harrenstien <[email protected]>
Subject: Query
To: [email protected]
Message-ID: <[email protected]>

Anyone remember how the MONSYM.H and MACSYM.H files were generated?
I was hoping that someone at SIERRA wrote a hack to make them from the
.REL files, but for all I know they are the result of running TECO macros
over the output of CVTUNV.
-------
 6-Nov-86 13:59:18-PST,1356;000000000011
Received: from Sierra.Stanford.EDU by SRI-NIC.ARPA with TCP; Thu 6 Nov 86 13:47:28-PST
Date: Thu 6 Nov 86 13:44:23-PST
From: Stu Grossman <[email protected]>
Subject: [Kcc User <[email protected]>: fseek problems!]
To: [email protected]
Message-ID: <[email protected]>

Mail-From: KCC-GUEST created at  6-Nov-86 12:27:30
Date: Thu 6 Nov 86 12:27:30-PST
From: Kcc User <[email protected]>
Subject: fseek problems!
To: [email protected]
Message-ID: <[email protected]>

We are having serious difficulties with fseeks in the KCC compiler.
After opening a file with fopen(), the initial fseek works like a charm.
Subsequent fseeks do not, however.  fseek() returns a 0 and ftell() indicates
the correct location, but we haven't really moved!  We believe that this may
be associated with a bug we found in fflush(), which is called in fseek().
Here is a simple code fragment that will demonstrate the fflush() bug:

#include <stdio.h>

main()
{
char line[80];
char *gets();

while(1)
{
fflush(stdin);
gets(line);
}
}

This program will NOT wait for input at gets()!!  Please get back to us ASAP
on this on.  Thanx muchly in advance.
-Eric Carter, Daniel Newman  Manufacturers Hanover Trust Co., New York
-------
-------
13-Nov-86 12:25:34-PST,1036;000000000001
Received: from Sierra.Stanford.EDU by SRI-NIC.ARPA with TCP; Thu 13 Nov 86 12:23:07-PST
Date: Thu 13 Nov 86 12:19:31-PST
From: Stu Grossman <[email protected]>
Subject: [Kcc User <[email protected]>: 'open' bug]
To: [email protected]
Message-ID: <[email protected]>

Mail-From: KCC-GUEST created at 13-Nov-86 12:17:51
Date: Thu 13 Nov 86 12:17:51-PST
From: Kcc User <[email protected]>
Subject: 'open' bug
To: [email protected]
Message-ID: <[email protected]>

I've run into a problem with 'open' - here is the scenario:
A file is opened O_RDWR, read from, then closed.  Later, the same
file is opened O_WRONLY|O_APPEND|O_TRUNC|O_CREAT, and written to - 
a new generation is created and the data written, not appended.  Work
around in this situation was to open it O_RDONLY the first time, rather
than O_RDWR.  What if I had wanted to write, as well as read?  Thanks,
Eric Carter. MHT, New York.
-------
-------
13-Nov-86 13:54:46-PST,1276;000000000001
Mail-From: IAN created at 13-Nov-86 13:41:44
Date: Thu 13 Nov 86 13:41:40-PST
From: Ian Macky <[email protected]>
Subject: Re: [Kcc User <[email protected]>: 'open' bug]
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

In the test case I just tried out I got different behavior than what you
described.  There was a bug, however - O_RDWR was failing to check for an
existing file first, and always creating a new version.  Here's the fix
for that:


;COMPARISON OF SS:<KCCDIST.LIB.USYS>OPEN.C.105 AND SS:<C.LIB.USYS>OPEN.C.114
;OPTIONS ARE    /3

**** FILE SS:<KCCDIST.LIB.USYS>OPEN.C.105, 4-23 (5683)
	** Note that if O_APPEND is set, we always look for an existing file
	** first.
	*/
	if (!(flags & (O_APPEND | O_T20_WROLD)))
**** FILE SS:<C.LIB.USYS>OPEN.C.114, 4-23 (6077)
	** Note that if O_APPEND or O_RDWR is set, we always look
	** for an existing file first.
	*/
	if (!(flags & (O_APPEND | O_RDWR | O_T20_WROLD)))
***************


If you are still having problems after putting in this fix, could you send
me a code fragment that demonstrates the problem?  Thanks...

--ian
-------
13-Nov-86 15:39:59-PST,797;000000000001
Received: from Sierra.Stanford.EDU by SRI-NIC.ARPA with TCP; Thu 13 Nov 86 15:29:38-PST
Date: Thu 13 Nov 86 15:25:51-PST
From: Bill Palmer <[email protected]>
Subject: two KCC bugs
To: [email protected]
Message-ID: <[email protected]>

The file in question can be found in FS1:<KCC.BENCH>BENCH.C on Sierra.

Bug 1)  

There is a declaration like

	stack[stackrange];  /* stackrange = 3 */

thatt KCC is very unhappy about.  The 4.3 compiler accepts it without complaint,
as does an old version of KCC.  

Bug 2)

Fixing up the declaration and compiling again, I get the compiler to generate
a new type of instruction: SETZBI.  Once upon a time the compiler used to
generate FLTRI's but I believe that was fixed long ago.

				Bill
-------
14-Nov-86 01:54:51-PST,521;000000000001
Received: from Sierra.Stanford.EDU by SRI-NIC.ARPA with TCP; Fri 14 Nov 86 01:45:54-PST
Date: Fri 14 Nov 86 01:42:19-PST
From: Bill Palmer <[email protected]>
Subject: KCC blows up on multiple file compilation
To: [email protected]
Message-ID: <[email protected]>

If you have a -Dfoo directive in the command line and compile several files
at once, KCC will give a "free: attempted to free invalid block" error.
Remove the -Dfoo, and it will work just fine.

				Bill
-------
14-Nov-86 13:09:57-PST,1317;000000000001
Received: from MC.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Fri 14 Nov 86 13:06:15-PST
Received: from WHORFIN.LCS.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 14 NOV 86  15:50:53 EST
Date: Fri, 14 Nov 86 15:48 EST
From: Rob Austein <[email protected]>
Subject: 8 bit characters?
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

How difficult would it be to add support for 8-bit characters (-x=ch8 or
some such)?  It would be Real Useful for two reasons:

1) Certain things, eg UDP packets, have to be formatted into left
   justified 8 bit bytes because of operating system limitations.

2) It turns out to be extremely useful to have network data in 8 bit
   bytes even when it is coming from some stream protocol, because it is
   much easier to extract header fields by casting structs and
   extracting bitfields.  Such header fields often cross byte boundries
   but rarely cross word boundries.

In both of these cases I currently kludge things by using a five line
assembly routine to convert from 9 to 8 bit pointers.  But it would be
real nice to just compile with the right switches and let the machine do
the dirty work.  Lot more portable too.  Seems like it shouldn't be much
trouble, especially compared to 7 bit bytes.

--Rob

14-Nov-86 17:25:03-PST,401;000000000001
Mail-From: KLH created at 14-Nov-86 17:24:49
Date: Fri 14 Nov 86 17:24:47-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: KCC blows up on multiple file compilation
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Fixed in current SYS:CC.EXE on SRI-NIC.
-------
14-Nov-86 17:39:58-PST,649;000000000001
Mail-From: KLH created at 14-Nov-86 17:28:14
Date: Fri 14 Nov 86 17:28:06-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: two KCC bugs
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

The SETZBI bug has been fixed (in SYS:CC.EXE on SRI-NIC).  The first "bug"
is not really a bug, I think.  Do you really think that declarations of the
form "foo[123];" should be interpreted as "int foo[123];"?  H&S says not;
a type-specified is required.  Only a function definition can omit the
type-specifier.
-------
14-Nov-86 17:54:59-PST,1741;000000000001
Mail-From: KLH created at 14-Nov-86 17:50:12
Date: Fri 14 Nov 86 17:50:09-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: 8 bit characters?
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Well, this would not be portable, anyway, since even for 8-bit-byte
machines you cannot predict what the byte ordering is going to be!  So
your struct declarations aren't going to work (at least, not portably)
and you will always need some machine dependent knowledge in order to
combine bytes into integer values, etc.

I'm not too thrilled about the idea of -x=ch8 because code compiled
for 8-bit bytes won't necessarily match up properly with code compiled
for 9-bit bytes.  To be safe, everything (including the library)
should be compiled with the same setting; but funny things will happen
with the library (eg STDIO won't be able to read 36-bit or 9-bit
files, and who knows what else).  It is possible to win (eg as for
7-bit bytes) only if you know what you are doing and are real careful.
It's true that most KCC code will work with 7,8, or 9, but the catch
is "most".

I'd say that using a hack routine to do your own casting conversion,
as you seem to be doing now, is the best idea.

A more ambitious notion would be to define additional types such as "char7"
and "char8" (and I suppose "char9" for completeness).  When using KCC these
would be significant; for other systems a typedef or macro would convert
them to simple "char".  I'm not sure how useful these would be or whether it
is worth messing around with more incompatible extensions to C; comments
welcome.
-------
22-Nov-86 23:05:28-PST,1479;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sat 22 Nov 86 22:51:42-PST
Date: Sat 22 Nov 86 23:47:03-MST
From: Frank J. Wancho <[email protected]>
Subject: PMAP functions
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

On occassion, you could get into a good argument about
a user program doing a PMAP vs. letting the monitor do
it for you.

In an attempt to make a primitive host alias lookup
program run a bit faster, I converted it to PMAP the
file instead of doing sequential fgets.  The results
were quite noteworthy, using the test of scanning a
112 disk page file for a non-existent string.  The
PMAP version was approximately five times faster in
CPU time and about three time faster in wall-clock
time.

If you wish to check it out for yourselves, the files
are in PS:<HOSTS> here.  ALIAS.*.4 is the fgets version
and ALIAS.*.5 is the PMAP version.  The file they read
is ALIASES.TXT in the same directory.

Now, the reason I bother to bring this up, in light of
the above results, is that I see that the NMIT C STDIO
portion of the runtime library is written to optionally
use PMAPped files for its I/O.  I just wondered if that
facility can be considered for the future for KCC.  Of
course, there is a catch: to manipulate PMAPped ASCII
files (7), you have to use the -X=ch7 compile option...

Anyway, it was just a thought I wanted to pass along.

--Frank
-------
24-Nov-86 15:51:25-PST,1021;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 24 Nov 86 15:34:12-PST
Date: Mon 24 Nov 86 16:33:57-MST
From: Frank J. Wancho <[email protected]>
Subject: Extension Request
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

Now that I have discovered that I can use PMAP within my C programs
and significantly improve the performance of these programs, I am
finding that the use of the -x=ch7 compiler option to be restrictive.
The reason is that I would like to be able to PMAP other than (7)
files and use the appropriate character pointer depending on byte
size of the file and not be limited to just one type of character
pointer within a program.

Therefore, I propose the following extension to the syntax:

char * to mean the same as it is now, pointers to 9-bit bytes
       in the internal format.

char7 * to create pointers to 7-bit bytes

char8 * to create pointers to 8-bit bytes

Comments welcome.

--Frank
-------
 4-Dec-86 16:47:33-PST,939;000000000001
Received: from Sierra.Stanford.EDU by SRI-NIC.ARPA with TCP; Thu 4 Dec 86 16:39:51-PST
Date: Thu 4 Dec 86 16:35:43-PST
From: Stu Grossman <[email protected]>
Subject: scanf bug
To: [email protected]
Message-ID: <[email protected]>

When scanf attempts to read a negative floating point number, it gets
mixed up and smashes stdio data structures.  This results in further stdio
calls acting pretty strange.

The statement looks like this:

	scanf("%f",&foo);

and the user types this:

-2.0

After that, printf and scanf stop working.

The bug is in the routine f_scanf in scanf.c.  The statement that looks
like:

	case '+':    if (--sf->width > 0) c = getc(sf->stream);

should be replaced by:

	case '+':    if (--sf->width) c = getc(sf->stream);

This might look a little familiar because the decimal input routine had
the same bug a while ago.

			Stu
-------
 6-Dec-86 16:32:53-PST,595;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sat 6 Dec 86 16:21:10-PST
Date: Sat 6 Dec 86 17:21:21-MST
From: Frank J. Wancho <[email protected]>
Subject: Problem with argc
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

The following code displays the value of argc to be 0
no matter how many args there are.

#include <stdio.h>
#include <ctype.h>

struct opt {
    int	disp;
    int	page;
    int	exit;
}

main(argc,argv)
int argc;
char *argv[];
{
    fprintf (stderr, "argc = %d\n", argc);
}
-------
 6-Dec-86 17:32:52-PST,444;000000000001
Mail-From: IAN created at  6-Dec-86 17:18:22
Date: Sat 6 Dec 86 17:18:18-PST
From: Ian Macky <[email protected]>
Subject: Re: Problem with argc
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

You need a semi after the structure definition; as is, you're declaring
main to be of type struct whatever, instead of int.

--ian
-------
 9-Dec-86 14:53:52-PST,562;000000000001
Received: from Sierra.Stanford.EDU by SRI-NIC.ARPA with TCP; Tue 9 Dec 86 14:39:07-PST
Date: Tue 9 Dec 86 13:11:43-PST
From: Stu Grossman <[email protected]>
Subject: time.h
To: [email protected]
Message-ID: <[email protected]>

The file time.h on <KCCDIST.INCLUDE.SYS> does not appear to be correct.  It
does not contain the definitions of the structure timeval for instance.
However, there are two other versions of time.h in <KCCDIST.LIB> and
<KCCDIST.LIB.USYS> that appear to be correct.

			Stu
-------
 9-Dec-86 15:23:42-PST,461;000000000001
Mail-From: KLH created at  9-Dec-86 15:12:48
Date: Tue 9 Dec 86 15:12:41-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: time.h
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Sigh.  As of when, today?  I had to put together a new snapshot and
did not have time to check out potential inconsistencies.
-------
 9-Dec-86 18:23:07-PST,514;000000000001
Received: from Sierra.Stanford.EDU by SRI-NIC.ARPA with TCP; Tue 9 Dec 86 18:13:18-PST
Date: Tue 9 Dec 86 17:13:25-PST
From: Stu Grossman <[email protected]>
Subject: Re: time.h
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

My bug report was in reference to the last version of KCC and utilities
that you released.  I beleive that I obtained it around September 26th.

		Stu
-------
12-Dec-86 17:04:13-PST,709;000000000001
Received: from Sierra.Stanford.EDU by SRI-NIC.ARPA with TCP; Fri 12 Dec 86 16:51:14-PST
Date: Fri 12 Dec 86 16:51:19-PST
From: Stu Grossman <[email protected]>
Subject: Bad code generation.
To: [email protected]
Message-ID: <[email protected]>

The following program does not produce correct results:

main(){
	int range;
	float ir;

	ir = 2.5;

	range = ir * 1000.0;

	printf("range=%d\n",range);

}

(Range should be 2500.)  However, if you compile it with  CC -O=  you get
the correct answer.  My CC.EXE is from about Nov 14th.

			Stu

P.S. Are you planning on using version numbers with CC.EXE?  It would be
     really handy.
-------
13-Dec-86 05:34:01-PST,715;000000000001
Mail-From: KLH created at 13-Dec-86 05:19:22
Date: Sat 13 Dec 86 05:19:20-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Bad code generation.
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Thanks, fixed.  A typo was producing a DMOVEM instead of a DMOVE as
part of the float->fix sequence; the strange thing is that this has
been there for a long time without being tickled.

The KCC version number is the .EXE file version number (this is why the
doc recommends that you retain it).

You can get the latest binary from SYS:CC.EXE on SRI-NIC.
-------
16-Dec-86 18:12:21-PST,1190;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Tue 16 Dec 86 18:04:04-PST
Date: Tue 16 Dec 86 19:04:16-MST
From: Frank J. Wancho <[email protected]>
Subject: More help, please
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

A couple of weeks ago I mentioned this program I wrote which
I converted to PMAP its input data file.  When I added the
required definitions and code, I found my counters being
trashed.  So, I just did a small experiment to move the
definitions to the end of the section, just prior to the
beginning of the code (all in the main() section), and the
counters came out "right" (i.e., untrashed), but the program
failed.

Now, I'm quite well aware that I'm "fooling with Mother Nature"
in using this PMAP construct - I lifted it from the NMIT runtime.
What I'd like to know is how to do it "right."  The source is
PS:<HOSTS>FIXHST.C on this machine.  Please tell me what's wrong
and how to fix it.  (The original test code I lifted this from
was designed to pmap one page, and I suspect I may have misunderstood
how to extend it to use more than one...)

Thanks,
Frank
-------
24-Dec-86 02:50:26-PST,1189;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Wed 24 Dec 86 02:36:03-PST
Date: Wed 24 Dec 86 03:01:51-MST
From: Frank J. Wancho <[email protected]>
Subject: Off by one?
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

OK, I *think* I've got this narrowed down...

Name          Length    Stowage    SF   Size now  Date       Time    CRC
============  ========  ========  ====  ========  =========  ======  ====
GO.BAT              14  Crunched  -21%        17  27 Dec 84   1:02a  20DB
ftell = 29, fdoff = 0, ocnt = 512, cnt = 483

[I've just read the first 29 bytes of header in the file and am about
to do an fseek relative to skip the Size now 17 data bytes.  So far so good.]

ftell = 46, fdoff = 46, ocnt = 0, cnt = 0

[and, sure enough, 29+17=46.]

READ.ME           1293  Crunched   35%       852   1 Apr 86   6:11p  4C5E

[Now, I've read another 29-byte header.  I *should* be at 46+29=75.
But, no!  ftell says I'm at 76!  f->sioocnt-f->siocnt = 29, but
f->siofdoff says 47 instead of 46!]

ftell = 76, fdoff = 47, ocnt = 512, cnt = 483

So, what changed f->siofdoff?

--Frank
-------
24-Dec-86 10:35:12-PST,884;000000000001
Mail-From: IAN created at 24-Dec-86 10:32:14
Date: Wed 24 Dec 86 10:32:12-PST
From: Ian Macky <[email protected]>
Subject: Re: Off by one?
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

I found the problem with fseek() et al.  When fgetc() counts out
siocnt and calls _filbuf(), siocnt = -1, which makes the following old
computation bogus.  Change it in FILBUF.C as follows:

;COMPARISON OF SS:<KCCDIST.LIB.STDIO>FILBUF.C.41 AND SS:<C.LIB.STDIO>FILBUF.C.42
;OPTIONS ARE    /3

**** FILE SS:<KCCDIST.LIB.STDIO>FILBUF.C.41, 1-51 (1326)
    f->siofdoff += (f->sioocnt - f->siocnt);		/* update position */
**** FILE SS:<C.LIB.STDIO>FILBUF.C.42, 1-51 (1326)
    f->siofdoff += f->sioocnt;
    if (f->siocnt > 0)
	f->siofdoff -= f->siocnt;
***************

-------
24-Dec-86 13:50:14-PST,995;000000000001
Received: from Sierra.Stanford.EDU by SRI-NIC.ARPA with TCP; Wed 24 Dec 86 13:38:36-PST
Date: Wed 24 Dec 86 13:16:34-PST
From: Stu Grossman <[email protected]>
Subject: Handling of Unix style directory specs in #include
To: [email protected]
Message-ID: <[email protected]>

With the following logical name definitions, the following program cannot
find the #include file.

	Job-wide:

	c: => DSK:,C:

	System-wide:

	c: => SRC:<KCCDIST.INCLUDE>,SRC:<KCCDIST.INCLUDE.SYS>

Note that the file  types.h  only exists in  SRC:<KCCDIST.INCLUDE.SYS>TYPES.H,
and that I am connected to  PS:<GROSSMAN>, and do not have a logical name DSK:
defined.
-----

#include <sys/types.h>

main() {}

-----
However, if I have no job-wide definition of c: then my program compiles just
fine.

Would it be possible to make KCC find that include file in spite of my
job-wide definition of c: (which includes system-wide c:)?

			Stu
-------
25-Dec-86 09:04:35-PST,1021;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Thu 25 Dec 86 09:02:50-PST
Date: Thu 25 Dec 86 10:02:47-MST
From: Frank J. Wancho <[email protected]>
Subject: Library search order
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

First, let me thank you, Ian, for finding and fixing my rather
obscure problem with fseek, etal.  The fixed LIBC did solve my
problem.

New problem (earier to describe): I have a "public" library I've
named LIBT20.REL, stuck in C:.  It contains my own version of
system().  However, when I do cc -m -lT20 prog.c, it picks up
the system from C:LIBC instead of mine.  But, if I do cc -c -m prog.c
and then LOAD prog,C:LIBT20/SE, it properly picks my system().

Therefore, I would like to request that the compiler be changed
to cause any user-specified library search requests ahead of
the default C:LIBC search.  I believe this is in consonance with
Unix conventions for ld options.

Thanks,
Frank
-------
29-Dec-86 21:45:06-PST,979;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 29 Dec 86 21:38:03-PST
Date: Mon 29 Dec 86 22:38:06-MST
From: Frank J. Wancho <[email protected]>
Subject: Extra Global Symbols
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

The following program produces two extra and undesired global
symbols, according to RELPRT, when the DEBUG flag is set.  The
symbols are FREAD and FWRITE, which are not produced, as expected,
when the DEBUG flag is off.  Both with and without the DEBUG flag
set produce identical preprocessor output.  What's going on?

--Frank
-------

#include <stdio.h>

#ifdef DEBUG
#define fread frd8
#define fwrite fwrit8
#endif

tst1(name,size,length,f)
char *name;
int size;
int length;
FILE *f;
{
#ifdef DEBUG
    fread(name,size,length,f);
    fwrite(name,size,length,f);
#else
    frd8(name,size,length,f);
    fwrit8(name,size,length,f);
#endif
}
-------
30-Dec-86 17:29:23-PST,655;000000000001
Received: from Sierra.Stanford.EDU by SRI-NIC.ARPA with TCP; Tue 30 Dec 86 17:20:47-PST
Date: Tue 30 Dec 86 17:20:34-PST
From: Stu Grossman <[email protected]>
Subject: pow()
To: [email protected]
Message-ID: <[email protected]>

Symptom:

	The pow routine (which performs exponentiation) does not work
	correctly if the exponent (the second arg) is negative, and the
	base (first arg) is positive.

	ie: pow(5,-2) does not produce 1/25.

Diagnosis:

	Missing minus sign in pow.c.  The line:

	    return 1.0 / power(x, y);

	should be:

	    return 1.0 / power(x, -y);


			Stu
-------
30-Dec-86 19:44:20-PST,502;000000000001
Received: from SUMEX-AIM.STANFORD.EDU by SRI-NIC.ARPA with TCP; Tue 30 Dec 86 19:33:39-PST
Received: from PANDA by SUMEX-AIM.STANFORD.EDU with Cafard; Tue 30 Dec 86 19:33:16-PST
Date: Tue 30 Dec 86 18:28:30-PST
From: Mark Crispin <MRC%[email protected]>
Subject: IOCTL/SGTTY
To: [email protected]
Postal-Address: 1802 Hackett Ave.; Mountain View, CA  94043-4431
Phone: +1 (415) 968-1052
Message-ID: <12267055513.7.MRC@PANDA>

When will these guys be available in KCC?
-------
31-Dec-86 18:05:30-PST,1046;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Wed 31 Dec 86 17:56:35-PST
Date: Wed 31 Dec 86 10:54:08-MST
From: Frank J. Wancho <[email protected]>
Subject: KCC availability
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

I have a couple of major conversions of microcomputer utility programs
for TOPS-20 ready to announce to several pertinent lists, including
the TOPS-20 list.  All of these packages depend on the availability of
the latest version of the KCC package.  However, I have yet to see an
announcement of KCC to the TOPS-20 list.  Is this an oversight, or are
you not quite ready to announce it to the world?  In either case, my
announcement will include its dependence on KCC.  My question is,
exactly what wording should I use as a pointer on how to obtain KCC,
i.e., "Inquiries on the availability of KCC should be directed to
_______.", with a netaddress in the blank or whatever you desire.

Please let me know soon.

Thanks,
Frank
-------
 3-Jan-87 09:17:38-PST,2950;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sat 3 Jan 87 09:07:39-PST
Date: Sat 3 Jan 87 10:06:32-MST
From: Frank J. Wancho <[email protected]>
Subject: malloc() problem
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

In the process of debugging a palloc(), I have discovered a case where
I can never force an allocation to come out with the character pointer
returned exactly on a page boundary, but one word below it.  This is
after taking into account the overhead words and the rounding.  The
specific case is when the initial allocation done by malloc() starts
out on an odd address.

The logic of palloc() is as follows:

1.  Initially malloc() the number of pages requested plus 2, in bytes.
2.  Find the first page boundary within the returned allocation.
3.  Take the difference between the address portions of the character
    pointers, and if they are equal, return the pointer returned by
    malloc().
4.  If they are different, free() the initial allocation.
5.  Take that difference (in words), multiply by four (to get bytes),
    and subtract two times the size of the overhead (2*16), round down
    the result to the next lower multiple of 8 (because malloc() will
    round it also, and we don't want more that we're asking for), then
    realloc() that amount.

At this point, we normally would have a block of memory "reserved"
which is large enough to hold the requested number of pages, plus the
overhead words, with the leading block before the page boundary now
allocated with its own pointer so that we can free() it in a moment.

5.  Now, malloc() the number of pages requested plus one page this time,
    and the resulting character pointer should be exactly on a page
    boundary.

6.  free() the intermediate allocation from step 4 and return the
    character pointer returned by malloc() in step 5.

Now, I could have "cheated" and simply created a palloc() that
returned two character pointers in its arguments, one pointing to the
page boundary, and the other the character pointer returned by the
initial malloc() which the user could then use to do his own free().

However, I prefer to implement a palloc() styled after malloc() and
calloc() in that they return simple character pointers which the user
can later free().  Unfortunately, in spite of all the rounding
efforts, there is a case where the amount allocated by the realloc()
step is one word less, and thus put the expected pointer one word
below the page boundary.  Note that this will also occur if palloc is
implemented in the malloc source itself, using the low-level calls
available there.

So, my request is to have you modify malloc() to guarantee that its
initial allocation starts out on an even address, thus guaranteeing
that all subsequent allocations will also land on even addresses.

Thanks,
Frank
-------
 4-Jan-87 08:02:11-PST,1344;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sun 4 Jan 87 07:47:30-PST
Date: Sun 4 Jan 87 08:46:30-MST
From: Frank J. Wancho <[email protected]>
Subject: Add -x=ch7 warning to CC.DOC
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

It is not obvious from the way the documentation is currently worded,
but simply compiling a program with the -x=ch7 does not automatically
take care of casting character pointers returned from runtime library
functions, such as from malloc(), to 7-bit byte pointers.  The user
must explicitly do this himself.  It would be a good idea to include
such a warning in that section of CC.DOC which discusses the
availability of the -x=ch7 option.

My workaround was to not use the -x=ch7 option and to just explicitly
coerce the returned byte pointer (from palloc(), in my case) using a
crude macro definition:

#define CHAR7(x)	(char *)((((int)x)&0777777)|0350700000000)

Of course, this is not for use with extended addressing...

I am still somewhat mystified why an explicit cast, as in:

	ptr = (char *)(palloc(size));

did not cause that same coersion when I used the -x=ch7 option for the
program which contained that line (while the definition of palloc()
was compiled without that option)...

--Frank
-------
 5-Jan-87 13:13:33-PST,506;000000000001
Mail-From: KLH created at  5-Jan-87 13:11:45
Date: Mon 5 Jan 87 13:11:30-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: KCC availability
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Just came back after two weeks.  I'll need a little time to catch up on
mail and look into some of the things you mention, but should be able
to answer your question soon.
-------
 6-Jan-87 15:52:32-PST,1589;000000000001
Mail-From: KLH created at  6-Jan-87 15:38:19
Date: Tue 6 Jan 87 15:38:17-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Library search order
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

KCC already does this.  Moreover, it does it in the same way UNIX does,
which is why your example isn't working:
	cc -m -lT20 prog.c
causes it to search LIBT20 before it loads prog.rel, because the -lT20
specification comes earlier.  This is mentioned a couple of times in
CC.DOC, although perhaps not as explicitly as it should be if you
missed it.

Anyway, try using
	cc -m prog.c -lT20
and see if that works for you.

There is a more general problem with loading library files which has
to do with the fact that C:LIBC is still .REQUESTed by every C module.
The main reason for this, I think, was to make it easy for people to
compile a module, then later say LOAD FOO and have the library automatically
searched if needed, without having to say LOAD FOO,C:LIBC.  The recent
expansion of KCC's loader-invocation capabilities (allowing .REL filenames,
-l library searches, etc) was meant to make it easier to use KCC as an
interface to LINK; and if this proved successful then eventually the
.REQUEST could be omitted from the assembler output and you would not have
any funny business going on any more.

What do you think?  Is it time to force people to either use KCC as the
interface to LINK, or specify C:LIBC explicitly?
-------
 6-Jan-87 16:37:33-PST,697;000000000001
Mail-From: KLH created at  6-Jan-87 16:37:12
Date: Tue 6 Jan 87 16:37:07-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Extra Global Symbols
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Ah, ha.  The symbol lookup for "fread" and "fwrite" during the #define
was causing KCC to think that those symbols were referenced by the program, 
although they were properly only seen by the preprocessor.  An oversight
in the insulation between preprocessor and parser, now fixed.
(not yet installed; is it urgent?)  Thanks for the convenient test
case!
-------
 6-Jan-87 17:22:23-PST,1697;000000000001
Mail-From: KLH created at  6-Jan-87 17:07:47
Date: Tue 6 Jan 87 17:07:44-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Handling of Unix style directory specs in #include
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Sigh.  The problem lies not in KCC but the library implementation of
the "open()" system call.  Actually, it would be fair to say that the
problem lies in the TOPS-20 monitor, because there just isn't any good
way for a user program to handle a relative filename; TOPS-20 refuses
to accept pathnames of the form "<.foo>filename".  If it did then we
could win since the conversion from a unix-style pathname to TOPS-20 style
would be absolutely trivial.  We've run into this same screw case
ourselves, and I've asked monitor people to look into what it would take
to make relative pathnames work (after all they already work when
specifying a directory name) but have never gotten any answers.
You want to try?  Please?

As far as KCC usage goes, you might try using the -I switch to provide
an alternate path, and enclose the sys/types.h in double-quotes instead
of angle brackets.  I know this is a pain.

Other suggestions for handling the problem are welcome.  If you really
think that there is some way for open() to wrestle the monitor into
submission, you're also welcome to try coding that approach.  Remember
it's not just the question of how to translate a relative name, which
isn't too hard; it's the question of what to do when a logical name is
involved and your first try fails.
-------
 6-Jan-87 17:22:25-PST,778;000000000001
Mail-From: KLH created at  6-Jan-87 17:16:18
Date: Tue 6 Jan 87 17:16:17-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: IOCTL/SGTTY
To: MRC%[email protected], [email protected]
cc: [email protected]
In-Reply-To: <12267055513.7.MRC@PANDA>
Message-ID: <[email protected]>

You're the first person, I think, to ask about those.  We don't have
any plans for them; those would be part of the UNIX simulation
environment (i.e. in the USYS part of the library).  Perhaps you would
like to code those, as you can then implement only those things which
are necessary or possible.  If not, then you'll have to be more
specific.  A full-fledged ioctl() is out of the question, although
most of sgtty() can probably be hacked.
-------
 6-Jan-87 17:37:22-PST,1387;000000000001
Mail-From: KLH created at  6-Jan-87 17:36:12
Date: Tue 6 Jan 87 17:36:11-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: KCC availability
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

If KCC is working well enough to support your stuff then you can go
ahead and refer to it.  I assume you are including .EXE files so that
most people will not need to immediately recompile things; you can
also include CC.EXE plus the C: directory if they need it.  Those who
would like to get their own sources for KCC, or get plugged into the
news, should send an email message to [email protected]
(this is also good for asking to be added to the INFO-KCC mailing
list).  Note this doesn't mean they will be able to get a copy of the
latest KCC immediately!  The current release doesn't include all of
the recent fixes.

You're right that no announcement has been made to the TOPS-20 list or
the world in general.  The "releases" up to now have collected a good
set of bug reports, so I'm glad we waited.  The next packaged release
will get more publicity, but of course it isn't ready just now;
various files have changed and it all needs to be bundled together and
tested again.  The bigger it gets the more painful it is.
-------
 6-Jan-87 18:37:20-PST,570;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Tue 6 Jan 87 18:31:10-PST
Date: Tue 6 Jan 87 19:31:26-MST
From: Frank J. Wancho <[email protected]>
Subject: Re: Extra Global Symbols
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Ken,

As far as I can tell, the external references to the global symbols
did not cause them to actually be loaded into the program.  Thus, no
big hurry as no real harm was done.

--Frank
-------
 6-Jan-87 23:52:16-PST,1021;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Tue 6 Jan 87 23:48:57-PST
Date: Wed 7 Jan 87 00:05:30-MST
From: Frank J. Wancho <[email protected]>
Subject: Re: Library search order
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Ken,

It seems that cc -m prog.c -lT20, in that order, does search
C:LIBT20.REL first.  However, that, as opposed to LOAD prog,C:LIBT20/SE,
results in an executable that is five disk pages larger.  I cannot
account for the difference without, somehow, causing LINK to generate
its log file when using the cc line...

Judging from that five page discrepancy, I would have to withhold
judgment on using the KCC interface to LINK or specifying an explicit
C:LIBC/SEARCH on a LOAD command.  At the moment, it appears that the
former is not quite right somehow.  Is the LINK action on a .REQUEST
exactly the same as a /SEARCH?

--Frank
-------
 9-Jan-87 14:43:54-PST,549;000000000001
Received: from Sierra.Stanford.EDU by SRI-NIC.ARPA with TCP; Fri 9 Jan 87 14:34:17-PST
Date: Fri 9 Jan 87 14:34:20-PST
From: Stu Grossman <[email protected]>
Subject: Bug with character pointers.
To: [email protected]
Message-ID: <[email protected]>

The following program generates bad code:

main(){
	char foo;
	foo = 'A';
	printf("string=%1s\n",&foo);
}

It looks like KCC treats foo like a normal int, and subsequently generates
the wrong kind of pointer to it.

		Stu Grossman
-------
12-Jan-87 17:16:23-PST,1555;000000000001
Mail-From: KLH created at 12-Jan-87 17:14:49
Date: Mon 12 Jan 87 17:14:37-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Bug with character pointers.
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Fixed in the latest KCC.  Note that there is a certain schizophrenia
exhibited in the way char objects are handled; chars by themselves are
stored in 36-bit words and treated just like "int"s, but char arrays
are packed as you would expect.  Strictly speaking, this makes it possible
to write code which will demonstrate inconsistent behavior when using char
objects arithmetically.  However, so far I have shied away from adding
the necessary instructions that would cause chars to ALWAYS be treated as
9-bit bytes; the overhead is ugly to contemplate.

This will probably have to be done someday, if only for the sake of rigid
adherence to the standard.  One possibility is to make a char be the
high-order byte in a word, so that signed chars are easily tested and
overflow is masked off naturally.  The other is to make a char be the low-order
byte so that shifts are not needed (although bit tests and masks will be).
Should contiguous "char" definitions in a structure/union be packed?  Note
that definitions outside of a structure (which have some symbol associated
with them) still need to occupy a whole word in order for their symbolic
identifier to remain distinct.
-------
13-Jan-87 15:56:26-PST,1107;000000000001
Mail-From: KLH created at 13-Jan-87 15:52:08
Date: Tue 13 Jan 87 15:52:04-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Add -x=ch7 warning to CC.DOC
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

I have improved CC.DOC as you suggested.  I think the reason your explicit
cast didn't seem to do anything was because palloc() was already defined
as returning a (char *), therefore your cast appeared unnecessary and caused
no actual conversion code to be generated.

Perhaps the best solution for this is to provide the library functions
_char7, _char8, and _char9 that will return char pointers of the appropriate
bytesize, given either a word address or byte pointer; these will work whether
using extended addressing or not.  If this seems reasonable, we'll set them
up.  I think this is preferable to inventing new types like "char7" and "char8"
since each new type requires KCC to deal with all the additional possible
combinations of types...
-------
13-Jan-87 18:23:22-PST,755;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Tue 13 Jan 87 18:10:23-PST
Date: Tue 13 Jan 87 19:11:43-MST
From: Frank J. Wancho <[email protected]>
Subject: Re: Add -x=ch7 warning to CC.DOC
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Ken,

I need to double-check... but, as I recall, I tried the case of
not declaring palloc and just casting its return value, with the
same result.  Of course, it's been a while.

Now, the library functions _char7, _char8, and _char9 appear to
be a good idea.  I'd like to try them before commenting further.

Thanks for looking into this problem.

--Frank
-------
24-Jan-87 17:51:22-PST,906;000000000001
Received: from Sierra.Stanford.EDU by SRI-NIC.ARPA with TCP; Sat 24 Jan 87 17:42:56-PST
Date: Sat 24 Jan 87 17:43:51-PST
From: Stu Grossman <[email protected]>
Subject: Problems with char variables revisited.
To: [email protected]
Message-ID: <[email protected]>

The following program demonstrates a problem with using char * pointers to
items of type char (without subscripts).

main(){
	char foo, *pfoo = &foo;

	foo = 111111;
	*pfoo = 'A';
	if (foo == 'A')	printf("\nMatch!!\n");
	else printf("\nComparison failed... foo=%d\n",foo);
}

Note that I artificially put some junk into foo.  In a more complex program,
there is a very good chance that foo will have junk in it when the routine
is first entered.

I think that using a byte pointer of the form  POINT 36,foo,35  would yield
more correct results in this case.

			Stu
-------
25-Jan-87 02:06:27-PST,882;000000000001
Mail-From: KLH created at 25-Jan-87 02:03:50
Date: Sun 25 Jan 87 02:03:47-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Problems with char variables revisited.
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

See my previous message about char objects.  This is just another manifestation
of the problem.  I now believe the right thing to do is simply use LDB/DPB
for ALL references, since the "char" type is mainly for storage efficiency,
not for execution efficiency.  The PDP-10 isn't the only machine that will
handle chars more slowly than ints (which are intended to be the most efficient
integer size).  I don't think this will take too long, but we'll see.  This
will probably be an incompatible change.
-------
25-Jan-87 08:50:49-PST,957;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sun 25 Jan 87 08:43:46-PST
Date: Sun 25 Jan 87 09:39:16-MST
From: Frank J. Wancho <[email protected]>
Subject: Declaration ordering matters
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

(I really wanted the Subject: line to be "Frustration!".)

I have a program that gathers stats from a very large log file.
I just made one change: I move the declaration of all the doubles
and ints from the beginning to the end of the declaration area.
The output between those two versions consisting of counters and
accumulators was quite different.  I do not understand why such
a small change should make such a large difference, especially
when the order of the declarations should not matter!  Is this
a known problem under certain circumstances, or would you like
me to try to reduce it to a demonstratable case?

--Frank
-------
25-Jan-87 09:50:48-PST,1104;000000000001
Received: from CS.COLUMBIA.EDU by SRI-NIC.ARPA with TCP; Sun 25 Jan 87 09:46:08-PST
Date: 25 Jan 1987  12:44 EST (Sun)
Message-ID: <[email protected]>
From: David Eppstein <[email protected]>
To:   Stu Grossman <[email protected]>
Cc:   [email protected]
Subject: Problems with char variables revisited.
In-reply-to: Msg of 24 Jan 1987  20:43-EST from Stu Grossman <GROSSMAN at Sierra.Stanford.EDU>

    Date: Saturday, 24 January 1987  20:43-EST
    From: Stu Grossman <GROSSMAN at Sierra.Stanford.EDU>

    I think that using a byte pointer of the form  POINT 36,foo,35  would yield
    more correct results in this case.

The trouble with doing it this way is there is no such thing as a
36-bit OWGBP.  I prefer Ken's idea of taking all refs to char vars
using byte ops.  Either that or explicitly zero the ones placed
on the stack and treat the case you mention as the programmer's fault.

Maybe also something should be done about the common subexpr
eliminator not masking off the extra bits when it eliminates an
DPB+LDB?

-de
25-Jan-87 11:05:46-PST,598;000000000001
Mail-From: KLH created at 25-Jan-87 10:56:43
Date: Sun 25 Jan 87 10:56:41-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Declaration ordering matters
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

That's hard to answer generally because in C the order of things often
does matter.  If the declaration area has no references whatsoever to
anything inside itself then yes, the order should not matter, and I would
like a demonstration case, thanks.
-------
26-Jan-87 09:04:55-PST,636;000000000001
Mail-From: KLH created at 26-Jan-87 09:00:49
Date: Mon 26 Jan 87 09:00:48-PST
From: Ken Harrenstien <[email protected]>
Subject: Please comment on this proposal
To: [email protected]
Message-ID: <[email protected]>

Currently KCC generates string constants using 7-bit bytes (ASCIZ).
This is inconsistent with all other uses of char, which assume 9-bit
bytes.  I think it would be best to simply do away with this and use
standard 9-bit bytes everywhere.  Can anyone think of any problems
this would cause?  I don't consider the slight additional storage (4
bytes/wd instead of 5) to be a problem.
-------
26-Jan-87 13:50:13-PST,690;000000000001
Mail-From: KLH created at 26-Jan-87 13:45:01
Date: Mon 26 Jan 87 13:44:58-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Declaration ordering matters
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Fortunately, it turns out that the problem is simple after all.  You
are using the values of some of your local variables BEFORE they have
been initialized to anything.  Thus they start with whatever was on
the stack at that time, and their ordering obviously determines what
kind of garbage you get.

Thanks to Ian for spotting this one.
-------
26-Jan-87 19:50:09-PST,631;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 26 Jan 87 19:48:37-PST
Date: Mon 26 Jan 87 20:27:43-MST
From: Frank J. Wancho <[email protected]>
Subject: Re: Declaration ordering matters
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Ken and Ian,

Thanks for taking the time to track that problem down.  Somehow I was
under the mistaken impression that some data types, especially ints
were automatically initialized to zero values.  I should have known
better.

--Frank
-------
27-Jan-87 09:43:41-PST,828;000000000001
Received: from Sierra.Stanford.EDU by SRI-NIC.ARPA with TCP; Tue 27 Jan 87 09:35:01-PST
Date: Tue 27 Jan 87 09:35:17-PST
From: Stu Grossman <[email protected]>
Subject: Re: Problems with char variables revisited.
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Regarding 36 bit OWGBPs, I made a proposal to the KL ucode group which would
have OWGBPs with a P field of 77 be defined as a 36 bit byte pointer.  LDB and
ILDB would work just fine.  I have heard rumors to the effect that they will
be implementing it in an upcoming KL ucode release.

The other option would be to use two-word global BPs.  Perhaps these would
only be used for word sized objects..

		Stu
-------
27-Jan-87 09:58:45-PST,1564;000000000001
Received: from CS.COLUMBIA.EDU by SRI-NIC.ARPA with TCP; Tue 27 Jan 87 09:55:35-PST
Date: 27 Jan 1987  12:51 EST (Tue)
Message-ID: <[email protected]>
From: David Eppstein <[email protected]>
To:   Stu Grossman <GROSSMAN%[email protected]>
Cc:   [email protected]
Subject: Problems with char variables revisited.
In-reply-to: Msg of 27 Jan 1987  12:35-EST from Stu Grossman <GROSSMAN at Sierra.Stanford.EDU>

    Date: Tuesday, 27 January 1987  12:35-EST
    From: Stu Grossman <GROSSMAN at Sierra.Stanford.EDU>

    Regarding 36 bit OWGBPs, I made a proposal to the KL ucode group
    which would have OWGBPs with a P field of 77 be defined as a 36
    bit byte pointer.  LDB and ILDB would work just fine.  I have
    heard rumors to the effect that they will be implementing it in an
    upcoming KL ucode release.

Yes, but would these be ILDB or LDB pointers?  There is only room for one...
(Not totally satisfactory for KCC since it has to work on today's microcode.)

    The other option would be to use two-word global BPs.  Perhaps
    these would only be used for word sized objects..

But then all (char *)s would have to be two words, because you don't
know how they were originally constructed.

Yet another option, which I now prefer to either of my previous proposals,
is to keep single chars in halfwords and use 18-bit pointers.  That way
non-pointer operations are as efficient as they are now plus your problems
with byte pointers and high order bits are solved.

-de
27-Jan-87 13:50:28-PST,650;000000000001
Received: from Sierra.Stanford.EDU by SRI-NIC.ARPA with TCP; Tue 27 Jan 87 13:35:18-PST
Date: Tue 27 Jan 87 11:39:44-PST
From: Stu Grossman <[email protected]>
Subject: Re: Problems with char variables revisited.
To: [email protected]
cc: GROSSMAN%[email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

If you think about it, you really only need 1 form of 36 bit byte pointer.
It can be turned from an LDB to an ILDB by just subtracting 1 from it, or
for consistency, you could do an ADJBP.

		Stu
-------
29-Jan-87 17:15:16-PST,437;000000000001
Received: from BIONET-20 (BIONET-20.ARPA) by SRI-NIC.ARPA with TCP; Thu 29 Jan 87 17:02:43-PST
Date: Tue 27 Jan 87 11:24:06-PST
From: Will Rusch <WILL@BIONET-20>
Subject: Extended Qsort
To: bug-kcc@BIONET-20
Message-ID: <12274318285.53.WILL@BIONET-20>


Any clue as to why qsort behaves differently when called from
a program loaded with extended addressing?  Still working on a
simple demonstration case...

	Will
-------
29-Jan-87 17:15:24-PST,623;000000000001
Received: from Score.Stanford.EDU by SRI-NIC.ARPA with TCP; Thu 29 Jan 87 17:10:05-PST
Date: Thu 29 Jan 87 16:14:32-PST
From: William "Chops" Westfield <[email protected]>
Subject: FTELL (and FSeek?) bug...
To: [email protected]
Message-ID: <[email protected]>

FTELL, or maybe FSEEK, does not check to be sure that the
byte size in the FDB of a file and the byte size of the user
open are the same.  Thus if a file is writen as 36 bit words,
and read as 8 bit bytes, positioning at the end of the file
actually positions the file about 1/4 from the beginning.

BillW
-------
29-Jan-87 23:30:08-PST,638;000000000001
Mail-From: KLH created at 29-Jan-87 23:16:16
Date: Thu 29 Jan 87 23:16:15-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Extended Qsort
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <12274318285.53.WILL@BIONET-20>
Message-ID: <[email protected]>

You are almost certainly calling qsort() with arguments that are not
properly declared.  The pointers must be (char *).  Make sure that
if you use malloc or calloc or friends (which return char *) that they
are predeclared as such, or attempts to cast them into other kinds of
pointers will screw up as well.
-------
 1-Feb-87 14:48:04-PST,1419;000000000001
Received: from Sushi.Stanford.EDU by SRI-NIC.ARPA with TCP; Sun 1 Feb 87 14:40:57-PST
Mail-From: JFINGER created at 31-Jan-87 18:55:39
Date: Fri 30 Jan 87 10:01:35-PST
From: Jeff Finger <[email protected]>
Subject: KCC LIBC.REL File
To: [email protected], [email protected]
Phone: (415) 723-1809 (office), (415) 852-9177 (home)
Message-ID: <[email protected]>
ReSent-Date: Sat 31 Jan 87 19:03:11-PST
ReSent-From: Jeff Finger <[email protected]>
ReSent-To: [email protected]
ReSent-Message-ID: <[email protected]>

Please pardon me if I am sending this message to the wrong person.
I am not at all sure who the right person is, and a pointer to that
person would be nearly as good as an answer.

I have been using KCC on SUSHI recently and wanted to make sure I am
running an up to date version. The SUSHI KCC files are copied from SCORE.
At SCORE there seem to be two CC.EXE's (LSYS: and NEW:) and two
include file directory structures (<KCC.C*> and <KCC.INCLUDE*>). By
running NEW:CC.EXE with C: pointing at <KCC.INCLUDE> everything seems
fine, but I notice that one file, <KCC.C>LIBC.REL, is newer (12/24/86)
and bigger than its counterpart on <KCC.INCLUDE> (12/4/86).
Where can I find out what was changed? (I could not find sources
on SCORE). Is there any practical difference?

Thanks,
-- Jeff Finger --

 9-Feb-87 04:28:04-PST,1299;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 9 Feb 87 04:21:11-PST
Return-Path: <[email protected]>
Received: from R20.UTEXAS.EDU by SIMTEL20.ARPA with TCP; Wed 4 Feb 87 10:54:11-MST
Date: Wed 4 Feb 87 11:54:09-CST
From: [email protected]
Subject: KCC
To: [email protected]
Message-ID: <[email protected]>
ReSent-Date: Wed 4 Feb 87 11:15:31-MST
ReSent-From: Frank J. Wancho <[email protected]>
ReSent-To: [email protected]
ReSent-Message-ID: <[email protected]>

	I have been unable to get any response form the KCC people at SRI.
	Is there any one else I can contact to get a copy of KCC for our
	20s on campus.  Some projects we have in mind are:
		GNUmicroEmacs	'so documentation for VMS, UNIX, micros and
				 the 20 are the same.'
		GNUplot		'same as above plus it get the 20 an easy
				 to use plotting package.'
		and others to come.
	Our user consultants are willing to spend time in getting the above
	programs to run in order to have the same documentation set.

	One of the consultants and myself will be talking about what we have
	done with GNUmicroEmacs.  It sure would be nice to have a version
	running for the 20.

	Any help would be appreciated.

	Don K
-------
 9-Feb-87 13:43:07-PST,614;000000000001
Mail-From: KLH created at  9-Feb-87 13:29:54
Date: Mon 9 Feb 87 13:29:45-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: KCC
To: [email protected], [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Huh?  All I can say is that I looked through all my mail for the last
two or three months and there's absolutely nothing from UTEXAS or
KASSEBAUM.  It's hard to respond to something you've never seen.
Anyway, I will follow up outside of the BUG-KCC list.
-------
10-Feb-87 16:22:03-PST,8049;000000000001
Return-Path: <[email protected]>
Received: from CS.COLUMBIA.EDU by SRI-NIC.ARPA with TCP; Wed 26 Nov 86 12:13:36-PST
Date: 26 Nov 1986  15:15 EST (Wed)
Message-ID: <[email protected]>
From: David Eppstein <[email protected]>
To:   Ian Macky <[email protected]>
Subject: advice?
In-reply-to: Msg of 25 Nov 1986  19:16-EST from Ian Macky <Ian at SRI-NIC.ARPA>
ReSent-Date: Tue 10 Feb 87 16:22:03-PST
ReSent-From: Ian Macky <[email protected]>
ReSent-To: "*SS:<C.DIST>BUG-KCC.MAIL.1"@SRI-NIC.ARPA
ReSent-Message-ID: <[email protected]>

I have kinda forgotten exactly what I was thinking of when I wrote
that code, so this is pretty approximate.  First, an overview of how
findcse finds common subexpressions (as its name suggests it does):

      - In the first loop it goes back through the peephole buffer and
	builds up a list of instructions that taken together calculate
	the value in the target register (the one given it as an
	argument).  In this case the list will just be the LDB.

      - For each other register that can hold a computed value, in
	parallel and with the state of each parallel computation held
	in what is called in the comments a register match machine,
	it goes back through the peephole buffer and sees if the
	instructions which calculate the value in that other register
	match the built up list of instructions.  This is the big loop.

      - If we ever get such a match, then the built up list of
	instructions for the target register value is not necessary,
	because we can instead copy the value in the matching register
	and it will be the same.  This is the common subexpr elimination.
	The redundant instructions will be removed from the buffer and
	the register containing the result will be the return value.
	The caller might emit a MOVE or might just use that register.

      - If all machines don't match, i.e. they find an instruction
	which is part of how the value in their result registers was
	calculated but which isn't part of how the target value was
	calculated, then we know that the target value is not a common
	subexpression so we have to keep its calculation (and return
	zero to show that we are still using the old register).

      - If we get to the beginning of the peephole buffer without any
	machine matching then again there is no common subexpression.

Building the target calculation instruction list (the first loop) should
be pretty straightforward.  The second and longer loop is where the
match machines go about their work.  Actually what happens is that we
look at each instruction and there will usually be only one register
changed, so only one match machine needs to be activated.  If the
instruction changing the register is the same as the one the machine
expects then the machine advances to the next instruction in the list;
if it doesn't match the machine aborts.  Most of the state of each
machine can be found in regmatch[], which says which instruction it
wants to see next or whether it's aborted.

One complication is that we have to tell whether a register used as an
index was not changed between the machine's calculation's use of it
and the target calculation's use.  This information is kept in isindex[].
Isindex[reg] is the pointer to the earliest use of that register in
the target calculation; if any machines are not yet that far back when
we see an instruction changing that reg then all those machines are aborted.
There is a possible bug here if the same register is used twice as an
index in the target calculation, with a change to it in between the
two uses; if this situation happens the first loop that builds the
target calculation instruction list should abort because the second
loop can't handle this, but I don't know whether it currently does.
Something that probably hasn't come up but might be made to with
sufficiently tricky code.  You should check this anyway (not that it
is related to your current bug).

Another complication is that, because of IDIVI, the register that a
machine wakes up on is not always the same as the one it uses as the
common subexpression value after a successful match.  There is another
array that keeps track of this information (I forget the name).

Yet another complication is to take care of instructions that can be
skipped over.  There is a SKIPPED field in the address mode type of
each instruction which the code should be looking at (I am pretty sure
it does but it's been a while).


What I've just described is the major function and description of
findcse, hopefully less cryptically than you've found the code to be.
The minor function of findcse was that it turned out to be convenient
to put ILDB folding there, which is where your problem lies.

LDB folding only happens when there is a single LDB (or DPB) as the
target calculation.  If we find a matching LDB first, this is just a
common subexpression like any other.  But if we find an IBP, then we
want to turn both instructions into an ILDB.  Currently there is one
thing which inhibits this, the jumped flag.  If we move back across a
jump out of the peephole buffer, this is not a problem for common
subexpressions but you don't want to pull the IBP across the jump
because then it won't happen if the jump gets taken.  The bug seems to
be that I didn't think that there might be other reasons not to move
the IBP forward (like in your situation where it is used in a MOVEM).

One solution might be to augment jumped to track whether the other
things happen (there are functions in some file which can tell you if
a register is used by an instruction, so this is not hard).  
Perhaps a better solution would be to, instead of pulling the IBP
forward, push the LDB back.  That is, drop the LDB instead of the IBP
and make the IBP into an ILDB instead of making the LDB into an ILDB.
This eliminates the jump problem and your problem, and you can flush
the jumped flag.  What it adds instead is that you have to make sure
nobody uses or changes the LDB register between the IBP and the LDB.
Again the functions I mention above can keep track of that, and you
just need a flag like jumped that says whether it's safe to make the fold.

Doing it this way seems to me to be always better in that the code is
equally good when it happens and it happens more often.  The only
problem I can think of is if there is an IBP then a jump then a LDB
into a register that is also calculated before the IBP and used at the
destination of the jump.  E.g. consider the following code:

    y=1; ++ptr; foo(x?y:*ptr)

it could compile into something like

	MOVEI R,1
	MOVEM R,y
	IBP ptr
	SKIPE S,x
	 JRST $1
	LDB T,ptr
	MOVE R,T
   $1:: ...

which would correctly become through my suggested change to findcse

	MOVEI R,1
	MOVEM R,y
	ILDB T,ptr
	SKIPE S,x
	 JRST $1
	MOVE R,T
   $1:: ...

but then I'm not sure whether changereg() would do the right thing
(i.e. nothing rather than fold the MOVE back up into the ILDB).  It
probably does but you should check to make sure (also make sure that
my understanding of ?: code generation is correct in that reg R is
reserved until the MOVE is generated so it can't already be generated
as LDB R,ptr above causing the changed ILDB fold to screw up).
If changereg is wrong in this situation there are probably also
situations not involving ILDB which would be wrong...


So anyway, in summary, I think changing the ILDB fold to leave the
ILDB where the IBP was rather than where the LDB was will work, but
you would also have to remove jumped, add a new flag which checks that
the LDB register wasn't used between the two instructions, and look in
a couple of other places to make sure there aren't more bugs.

Sorry for making this message much longer and more complicated than it
probably deserves.  I hope you've gotten something out of it...

"*gurgle*  *splash*"?  No comprendo....

-de
13-Feb-87 20:29:42-PST,329;000000000001
Received: from BIONET-20 ([128.92.192.5]) by SRI-NIC.ARPA with TCP; Fri 13 Feb 87 20:21:10-PST
Date: Fri 13 Feb 87 10:13:15-PST
From: Will Rusch <WILL@BIONET-20>
Subject: registers
To: bug-kcc@BIONET-20
Message-ID: <12278761837.23.WILL@BIONET-20>


How does one heed kcc's warning of a doubly widened register?
-------
14-Feb-87 12:44:33-PST,414;000000000001
Mail-From: KLH created at 14-Feb-87 12:40:25
Date: Sat 14 Feb 87 12:40:23-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: registers
To: will@[128.92.192.5]
cc: [email protected], [email protected]
In-Reply-To: <12278761837.23.WILL@BIONET-20>
Message-ID: <[email protected]>

That's an internal error -- a bug.  Send me the code that makes this
happen and I'll fix it.
-------
16-Feb-87 16:42:36-PST,881;000000000001
Mail-From: KLH created at 16-Feb-87 16:30:52
Date: Mon 16 Feb 87 16:30:49-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: registers
To: WILL%[email protected]
cc: [email protected], [email protected]
In-Reply-To: <12279589726.23.WILL@BIONET-20>
Message-ID: <[email protected]>

Thanks for the bug-inducing sample code, I found the problem and fixed it.
Unfortunately the latest compiler is not compatible so you can't just
copy over the .EXE and win.  For the time being, try to avoid using unary
negate on a float operand; subtract it from something instead.  For
example, in your code there is a "-bgs[i]" at the start of an expression;
if you move it to the end of that expression (so it looks like a subtraction)
it will work.  I hope this isn't too much of a pain... I am trying hard to
finish up the new stuff.
-------
15-Mar-87 23:53:02-PST,390;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Sun 15 Mar 87 23:38:44-PST
Date: Mon, 16 Mar 1987  02:36 EST
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: RESET%

Somewhere in the initialization process before calling main(),
something should be doing a RESET% jsys.
16-Mar-87 13:23:07-PST,608;000000000001
Mail-From: KLH created at 16-Mar-87 13:17:39
Date: Mon 16 Mar 87 13:17:35-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: RESET%
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Well, yes.  If you look at the library CRT.C module you will see that
the TOPS-20/TENEX startup code is doing a RESET%.  This happens only
a few instructions into the execution.  I'm not sure if you mean that
the existence, rather than non-existence, of the RESET% is a misfeature.
-------
16-Mar-87 13:52:53-PST,1319;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Mon 16 Mar 87 13:38:00-PST
Date: Mon, 16 Mar 1987  16:35 EST
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   Ken Harrenstien <[email protected]>
Cc:   [email protected], [email protected]
Subject: RESET%
In-reply-to: Msg of 16 Mar 1987  16:17-EST from Ken Harrenstien <[email protected]>

    Date: Monday, 16 March 1987  16:17-EST
    From: Ken Harrenstien <[email protected]>

    Well, yes.  If you look at the library CRT.C module you will see that
    the TOPS-20/TENEX startup code is doing a RESET%.  This happens only
    a few instructions into the execution.  I'm not sure if you mean that
    the existence, rather than non-existence, of the RESET% is a misfeature.

Hmm.  No, I really did mean non-existance.  I noticed the problem
because I've been using IDDT to debug a C program that does IPCF and
has a named PID, and the program consistantly crashed if I didn't
manually do a RESET% before restarting it (because the PID was already
in use).  I put a breakpoint at JSYS&JSYS+3 and $$P'd it, and it
didn't ever execute RESET% (the first call was DVCHR%, I think).

Maybe my sources are screwed up or something.  I'll let you know if it
doesn't turn out to be a local bug.
16-Mar-87 13:53:06-PST,1246;000000000001
Mail-From: KLH created at 16-Mar-87 13:47:01
Date: Mon 16 Mar 87 13:46:47-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: RESET%
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

The RESET% isn't executed by jsys() as it is part of the low-level startup
(look at the SSTART: label).  I suspect that what you are seeing is yet
another aspect of the brain-damaged way that TOPS-20 cleans things up; all
that RESET% really seems to do is say "hey, do this if you've got a spare
hour or two, will you" and then comes right back to the user program,
which then tries to do something that fails because the cleanup hasn't
yet actually been done!

This often happens for JFNs.  MIDAS, for example, is too fast for TOPS-20
and if you give a new MIDAS command the same as a previous one (which was
interrupted) then you will often fail, because the old output-file JFN
has not yet been cleared away.  Most programs don't encounter this problem
as it takes them a while to get around to doing whatever it is they are
supposed to do.  I bet you never knew that DEC software was designed to be
slow!
-------
16-Mar-87 14:08:04-PST,2362;000000000001
Received: from UTAH-SCIENCE.ARPA by SRI-NIC.ARPA with TCP; Mon 16 Mar 87 14:04:11-PST
Date: Mon 16 Mar 87 14:29:51-MST
From: "Nelson H.F. Beebe" <[email protected]>
Subject: KCC internal error -- help
To: [email protected]
cc: [email protected]
X-US-Mail: "Center for Scientific Computation, South Physics, University of Utah, Salt Lake City, UT 84112"
X-Telephone: (801) 581-5254
Message-ID: <[email protected]>

Several programs have compiled fine with the new KCC, but it
fails on MAKE.C,  with and without  optimization.  I am  now
unable to update MAKE without tedious reverting to the older
version of KCC.   When the internal  error is detected,  KCC
should set a flag  which prevents FAIL  from running, so  no
.REL file is produced.  This  took me awhile to track  down,
because I did MAKE and went down the hall; the error message
scrolled off the screen and  the new MAKE.EXE when run  died
with an illegal instruction violation which I traced to junk
being left on the stack in  make() in MAKE.C which then  got
executed by the POPJ  17,0.  Recompilation of MAKE.C  showed
the error and provided the explanation.

Here is a PHOTO log:

[PHOTO:  Recording initiated  Mon 16-Mar-87 2:21PM]

 TOPS-20 Command processor 5(712)
@
@kcc -DKCC_20 -O=-all make.c
KCC:	make

Warning at make+85, line 569 of make.c:
void
Internal error - Register allocation: unreleased registers left over from previous code

Warning at make+85, line 569 of make.c:
void
Internal error - Register allocation: release of a spilled register
<BEEBE.MAKE>MAKE.PRE.1
<BEEBE.MAKE>MAKE.FAI.1
FAIL:  make
LINK:	Loading
^C
@v make.*.0

   APS:<BEEBE.MAKE>
 MAKE.C.23;P777752          5 11270(7)   14-Mar-87 12:31:06 BEEBE     
   .HLP.15;P777752          3 6220(7)    13-Mar-87 18:39:32 BEEBE     
   .REL.1;P777752           5 2481(36)   16-Mar-87 14:22:10 BEEBE     
   .TAGS.4;P777752          2 3349(7)    16-Mar-87 12:03:48 BEEBE     

 Total of 15 pages in 4 files
@get sys:kcc
@i verSION 
 College of Science DecSystem-20, TOPS-20 Monitor 5.4(1022)
 TOPS-20 Command processor 5(712)
 Program is KCC
@v sys:kcc.exe.0

   PS:<SUBSYS.KCC>
 KCC.EXE.558;P777752      147 75264(36)  10-Mar-87 14:07:57 KLH       
@pop

[PHOTO:  Recording terminated  Mon 16-Mar-87 2:23PM]

-------
16-Mar-87 14:22:47-PST,911;000000000001
Mail-From: KLH created at 16-Mar-87 14:18:27
Date: Mon 16 Mar 87 14:18:14-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: KCC internal error -- help
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

True errors do prevent FAIL from running.  The "register allocation"
messages, however, are currently "warnings" rather than errors.  I can
only guess that this is because in the past, such problems only
resulted in inefficiencies rather than in incorrect code, and it was
still preferable to produce something instead of giving up.

This bug should be associated with a specific routine in the source
being compiled.  If you can narrow it down to a single routine, mail
that to me (KLH), otherwise I'll get to it when I get all the files
transferred.
-------
16-Mar-87 14:37:48-PST,2918;000000000001
Received: from UTAH-SCIENCE.ARPA by SRI-NIC.ARPA with TCP; Mon 16 Mar 87 14:33:55-PST
Date: Mon 16 Mar 87 15:21:27-MST
From: "Nelson H.F. Beebe" <[email protected]>
Subject: BUG.C -- register allocation error demo
To: [email protected]
cc: [email protected]
X-US-Mail: "Center for Scientific Computation, South Physics, University of Utah, Salt Lake City, UT 84112"
X-Telephone: (801) 581-5254
Message-ID: <[email protected]>

/* BUG.C -- KCC internal register allocation error demonstration */
/*
 *	Do the actual making for make
 */

#include "h.h"

#ifdef EON
#include <sys/stat.h>
#include <sys/err.h>
#endif

#ifdef KCC_20
#include <stat.h>
#include <errno.h>
#endif

#ifdef MSC
#include <sys/stat.h>
#include <errno.h>
#endif

#ifdef OS9
#include <time.h>
#include <os9.h>
#include <modes.h>
#include <direct.h>
#include <errno.h>
#endif

#ifdef UNIX
#include <sys/stat.h>
#include <sys/errno.h>
#endif

#ifdef VMS
#include <stat.h>
#include <errno.h>
#endif
/*
 *	Recursive routine to make a target.
 */
int
make(np, level)
NAMEP		np;
int			level;
{
	register DEPENDP	dp;
	register LINEP		lp;
	register DEPENDP	qdp;
	time_t				dtime = 1;
	bool				didsomething = 0;


	if (np->n_flag & N_DONE)
		return 0;

	if (!np->n_time)
		modtime(np);		/*  Gets modtime of this file  */

        if (debug)
	{
	    fprintf(stderr,"MAKE(%s,%d):\tTIME(%ld)\n",np->n_name,(int)level,
	        (long)np->n_time);
	}

	if (rules)
	{
		for (lp = np->n_line; lp; lp = lp->l_next)
			if (lp->l_cmd)
				break;
		if (!lp)
			(void)dyndep(np);
	}

	if (!(np->n_flag & N_TARG) && np->n_time == (time_t)0)
		fatal("Don't know how to make %s", np->n_name);

	for (qdp = NULL_DEPENDP, lp = np->n_line; lp; lp = lp->l_next)
	{
		for (dp = lp->l_dep; dp; dp = dp->d_next)
		{
			(void)make(dp->d_name, level+1);
			if (np->n_time < dp->d_name->n_time)
				qdp = newdep(dp->d_name, qdp);
			dtime = max(dtime, dp->d_name->n_time);
		}
		if (!quest && (np->n_flag & N_DOUBLE) && (np->n_time < dtime))
		{
			make1(np, lp, qdp);	/* free()'s qdp */
			dtime = 1;
			qdp = NULL_DEPENDP;
			didsomething++;
		}
	}

	np->n_flag |= N_DONE;

	if (quest)
	{
		long		t;

		t = np->n_time;
		time(&np->n_time);
		return t < dtime;
	}
	else if (np->n_time < dtime && !(np->n_flag & N_DOUBLE))
	{
	        if (debug)
		{
			fprintf(stderr,"\tTIME(%ld) < %ld\n",
				(long)np->n_time,(long)dtime);
		}
		make1(np, NULL_LINEP, qdp);	/* free()'s qdp */

/* WRONG!! Must not change dependent time to current time.   Otherwise target
   will always be found older than its dependents.
		time(&np->n_time);
   Get real modification time instead!! */

		modtime(np);
	}
	else if (level == 0 && !didsomething)
		printf("%s: `%s' is up to date\n", myname, np->n_name);
	return 0;
}
-------
16-Mar-87 14:52:49-PST,647;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Mon 16 Mar 87 14:38:42-PST
Date: Mon, 16 Mar 1987  16:49 EST
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   Ken Harrenstien <[email protected]>
Cc:   [email protected]
Subject: RESET%
In-reply-to: Msg of 16 Mar 1987  16:46-EST from Ken Harrenstien <[email protected]>

You're dead right.  It's hitting SSTART consistantly (of course).

It's a good thing you just handed me that theory or I would have spent
the next ten hours groveling through the monitor trying to find out
what was wrong.

Thanks, and sorry for the noise.
16-Mar-87 15:07:53-PST,808;000000000001
Mail-From: KLH created at 16-Mar-87 14:53:11
Date: Mon 16 Mar 87 14:53:07-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: BUG.C -- register allocation error demo
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Uh, I know I asked that all bugs go to BUG-KCC, but longish source code
is probably better sent directly to the debugger rather than being inflicted
on everybody.  One other comment: bug examples should be self-contained,
i.e. without any #includes.  This is easy to do with CC -E foo.c > foo.raw
(if foo.raw doesn't exhibit the bug, well that is useful news as it
isolates the problem to the preprocessor!)

I'll get on this right away.
-------
16-Mar-87 16:07:56-PST,963;000000000001
Mail-From: KLH created at 16-Mar-87 15:54:18
Date: Mon 16 Mar 87 15:54:12-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: BUG.C -- register allocation error demo
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

OK, I found the problem.  The increment/decrement operators, when applied
to a char-type object, were allocating an extra register for no good reason.
A new version of KCC is available from SYS:NCC.EXE on SRI-NIC.  Note it is
called NCC, not CC, because it also incorporates some optimizations which I
want to test further before making it the standard CC (and the system is
a bit slow for testing right now).

By the way, it would be a bit faster if you defined the "bool" type to be
int instead of unsigned char on the PDP-10, as the latter saves no space
except in structure definitions.
-------
16-Mar-87 18:07:57-PST,1767;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Mon 16 Mar 87 17:59:37-PST
Date: Mon, 16 Mar 1987  20:57 EST
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: Another bug for you (unions and structs, wrong code generated)

I must admit that this is one of the more amusing compiler errors I
can recall seeing.  It is clearly on drugs by the time it gets to the
return() statement....

Here's the C code:

unsigned a,b,c,d;

int atoina()
{
    union {
	int number;
	struct {
	    unsigned   : 4;
	    unsigned a : 8;
	    unsigned b : 8;
	    unsigned c : 8;
	    unsigned d : 8;
	} address;
    } crock;
    crock.number = 0;
    crock.address.a = a;
    crock.address.b = b;
    crock.address.c = c;
    crock.address.d = d;
    return(crock.number);
}

And here's the FAIL code:

	TITLE	kccbug
	.REQUEST C:LIBc.REL
	$$CVER==<2,,1>
	INTERN $$CVER
	OPDEF ADJBP [IBP]
DEFINE %CHRBP(A,M)
<	SETO A,
	ADJBP A,M
>
IFNDEF ERJMP,< OPDEF ERJMP [JUMP 16,] >
OPDEF ERJMPA [ERJMP]
OPDEF	XMOVEI	[SETMI]
	DEFINE IFIW <SETZ >
XBLT==<020000,,0>
	TWOSEG	400000	
	RELOC	0	
	RELOC	400000	
	DEFINE %%CODE <RELOC>
	DEFINE %%DATA <RELOC>
PURGE IFE,IFN,IFG,IFGE,IFL,IFLE,IFDEF,IFNDEF,IFIDN,IFDIF

	%%DATA
a:	BLOCK	1
b:	BLOCK	1
c:	BLOCK	1
d:	BLOCK	1

	%%CODE
atoina:
	PUSH 17,[0]
	MOVE 4,a
	DPB 4,[341017,,1]
	MOVE 5,b
	DPB 5,[241017,,1]
	MOVE 6,c
	DPB 6,[141017,,1]
	MOVE 7,d
	DPB 7,[41017,,1]
	MOVEI 1,0
	ADJSP 17,-1
	POPJ 17,

$$CPKI==0
	INTERN $$CPKI
$$CPKA==0
	INTERN $$CPKA

	LIT
	EXTERN	$$$CPU
	EXTERN	$$$CRT
	INTERN	a
	INTERN	b
	INTERN	c
	INTERN	d
	INTERN	atoina
	END


--Rob
16-Mar-87 18:08:25-PST,1072;000000000001
Received: from Score.Stanford.EDU by SRI-NIC.ARPA with TCP; Mon 16 Mar 87 18:01:38-PST
Date: Mon 16 Mar 87 17:58:49-PST
From: Peter Samson <[email protected]>
Subject: Problem with KCC-3
To: [email protected]
Message-ID: <[email protected]>

The following code extract (sorry I haven't had a chance to boil it
down further) causes error messages about register allocation.


extern int  Func1();

main()
{
   Proc0();
}

char      Char2Glob;

Proc0()
{
   int      IntLoc1;
   int      IntLoc2;
   int      IntLoc3;
   char      CharLoc;
   char      CharIndex;
   int       EnumLoc;
   register unsigned long   i;   /* Use appropriate precision - FW */

for (i = 0; i < 500000; ++i)
{
   IntLoc1 = 2;
   EnumLoc = 2;

   for (CharIndex = 'A'; CharIndex <= Char2Glob; ++CharIndex)
      if (EnumLoc == Func1(CharIndex, 'C'))
         Proc6(1, &EnumLoc);
   Proc2(&IntLoc1);
}
}

Proc1(PtrParIn)
int  PtrParIn;
{
}


It used to compile OK (I think) with the previous release of KCC.
-------
16-Mar-87 18:37:51-PST,832;000000000001
Mail-From: KLH created at 16-Mar-87 18:25:08
Date: Mon 16 Mar 87 18:25:05-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Problem with KCC-3
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Looks like synchronity at work.  Beebe@UTAH-SCIENCE beat you by a few
hours to this bug report, and the fix is already installed.  Basically
++ or -- of a char variable generates those messages.  It's hard to
believe, but nothing in any KCC or NIC software ever tries this!  I do
have a suite of KCC test programs intended to beat on all operands and
type combinations, and that op got left out.  Sigh.

Since you don't have FTP I'll send you the source fix in a separate message.
-------
17-Mar-87 21:06:35-PST,1240;000000000001
Mail-From: KLH created at 17-Mar-87 20:55:08
Date: Tue 17 Mar 87 20:55:04-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Another bug for you (unions and structs, wrong code generated)
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Boy, that one was tough.  It's fixed now in the latest installed CC on
SRI-NIC (see the INFO-KCC message).  There were two separate problems,
one having to do with unnamed bitfields in structures (this fouled up
the too-clever trick that was being used to know whether struct/union
parsing was at the start of a word or not!), and the other having to
do with some more oversights in the peephole optimizer -- among other
things the common subexpression code only had a limited knowledge of
what instructions modified memory, and didn't realize that byte
pointers could point to the same thing as normal instruction
addressing.  I am slowly fixing all of that by using tables which
completely describe the behavior of every instruction, but full
conversion will take quite a while.

At least the fixed code now does better optimization than before!
-------
18-Mar-87 15:02:07-PST,594;000000000001
Received: from Score.Stanford.EDU by SRI-NIC.ARPA with TCP; Wed 18 Mar 87 14:48:46-PST
Date: Wed 18 Mar 87 14:39:49-PST
From: William "Chops" Westfield <[email protected]>
Subject: KCC problem?
To: [email protected]
Message-ID: <[email protected]>

I have some files open in mode "rb7" and "wb7", and am doing a block copy
from one to the other using fread and fwrite.  Something is going and
turning bare LFs into CRLFs (I suspect that it is FREAD, since it also
seems to copy an incorrect number of characters...

I this a bug ?

BillW
-------
18-Mar-87 18:31:38-PST,930;000000000001
Mail-From: IAN created at 18-Mar-87 18:17:14
Date: Wed 18 Mar 87 18:17:10-PST
From: Ian Macky <[email protected]>
Subject: Re: KCC problem?
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

    I have some files open in mode "rb7" and "wb7", and am doing a block copy
    from one to the other using fread and fwrite.  Something is going and
    turning bare LFs into CRLFs (I suspect that it is FREAD, since it also
    seems to copy an incorrect number of characters...

    I this a bug ?

No, that's the intended behavior.  Unless otherwise requested, I/O to
7-bit files converts external CRLF to NL, and internal NL on output to
CRLF.  Note that this is only done automatically for *7-bit*, assumed
text files.  To force no conversion, add "C-" to the fopen() flags,
e.g. "rb7C-".

--ian
-------
19-Mar-87 14:31:47-PST,898;000000000001
Mail-From: KLH created at 19-Mar-87 14:25:11
Date: Thu 19 Mar 87 14:24:58-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: KCC problem?
To: [email protected], [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Actually, according to the documentation, "rb7" should work, as the
"b" for binary always implies no conversion.  In this case I feel
the documentation is more correct than the code, so let's fix the code.

In the meantime, however, it's true that the addition of "C-" should
suppress the unwanted/unnecessary conversion.

Note that fread and fwrite are not guaranteed to work for byte sizes other
than 9, by the way.  It is just as efficient, perhaps more so, to do your
own getc/putc loop if all you are concerned with is copying buffers.
-------
19-Mar-87 14:31:57-PST,852;000000000001
Date: Thu 19 Mar 87 14:24:58-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: KCC problem?
To: [email protected], [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Actually, according to the documentation, "rb7" should work, as the
"b" for binary always implies no conversion.  In this case I feel
the documentation is more correct than the code, so let's fix the code.

In the meantime, however, it's true that the addition of "C-" should
suppress the unwanted/unnecessary conversion.

Note that fread and fwrite are not guaranteed to work for byte sizes other
than 9, by the way.  It is just as efficient, perhaps more so, to do your
own getc/putc loop if all you are concerned with is copying buffers.
-------
22-Mar-87 22:40:37-PST,381;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sun 22 Mar 87 22:36:51-PST
Date: Sun 22 Mar 87 23:36:19-MST
From: Frank J. Wancho <[email protected]>
Subject: Problem with strncpy()
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

strncpy() does not terminate the target string with a null.

--Frank
-------
23-Mar-87 15:59:50-PST,1052;000000000001
Mail-From: IAN created at 23-Mar-87 15:43:53
Date: Mon 23 Mar 87 15:43:43-PST
From: Ian Macky <[email protected]>
Subject: Re: Problem with strncpy()
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

    strncpy() does not terminate the target string with a null.

According to CARM I, section 11.2.9:

    "strncpy copies exactly n characters to s1.  It copies up to n
    characters from s2.  If there are fewer than n characters in
    s2 before the terminating null character, then null characters
    are written into s1 as padding until exactly n characters have
    been written.  If there are n or more characters in s2, then
    only n characters are copied, and so only a truncated copy of
    s2 is transferred to s1.  IT FOLLOWS THAT THE COPY IN S1 IS
    TERMINATED WITH A NULL BY STRNCPY ONLY IF THE LENGTH OF S2
    (NOT COUNTING THE TERMINATING NULL) IS LESS THAN N."

CARM II says the same thing.

--ian
-------
23-Mar-87 19:39:35-PST,807;000000000001
Mail-From: KLH created at 23-Mar-87 19:26:12
Date: Mon 23 Mar 87 19:26:07-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: KCC problem?
To: [email protected], [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

By the way, I went and checked on the actual behavior for modes "rb7"
and "wb7", and found that they work precisely as documented -- there
is no LF to CRLF conversion happening, at least not for my test
program, using both getc/putc and fread/fwrite.  So there should be no
KCC bug, and using "C-" should not be necessary.

I guess you'll have to look more closely into the nature of the problem,
or provide a simple test case that demonstrates a bug.
-------
23-Mar-87 21:54:40-PST,709;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 23 Mar 87 21:40:22-PST
Date: Mon 23 Mar 87 22:39:48-MST
From: Frank J. Wancho <[email protected]>
Subject: Problem with LINK
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

I have a program which has the following abbreviated contents:

#include <stdio.h>
#include <string.h>

:
	char	*rindex();
:
	reference to rindex
:
char *
rindex(p,s)
followed by a local definition of rindex().

LINK complains that RINDEX is multiply defined.

Shouldn't my local definition have superceded the one in
the library?  Shouldn't LINK have been oblivious to this?

--Frank
-------
23-Mar-87 21:54:43-PST,515;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 23 Mar 87 21:49:23-PST
Date: Mon 23 Mar 87 22:48:17-MST
From: Frank J. Wancho <[email protected]>
Subject: Re: Problem with strncpy()
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Ian,

I guess I can see the usefulness of the defined action
of strncpy() as opposed to the intuitive action I expected.

--Frank
-------
23-Mar-87 23:08:13-PST,1432;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 23 Mar 87 22:53:19-PST
Date: Mon 23 Mar 87 23:08:56-MST
From: Frank J. Wancho <[email protected]>
Subject: Command line expansion of wildcards
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

Is the trouble and effort taken by the runtime startup to expand
wildcards counterproductive?  It seems to me that the expansion is a
function of the Unix shell, not required by the C standards to be
emulated, or is it?  Where does one draw the line?

Wasn't the TOPS-20 EXEC deliberately designed not to attempt to parse
a program command as if it contained filespecs, and for good reasons?
Why then should a KCC program do that for the user, and not well at
that?  If it were to do it well, then perhaps the assumed generation
number would be * instead of 0?  That's maybe a grey area?  I rather
have the programmer given the choice by providing a function to be
called to do the expansion with a flag option for * or 0, or let the
programmer do his own expansion as needed.

The real problem is the user is not presented with a consistent
TOPS-20 interface in a TOPS-20 environment.  Other TOPS-20 programs do
not require the user to enclose an argument in double-quotes.  Why
should the user have to remember which is an "ordinary" TOPS-20
program and which is a KCC program?

--Frank
-------
24-Mar-87 08:23:20-PST,982;000000000001
Mail-From: KLH created at 24-Mar-87 08:08:14
Date: Tue 24 Mar 87 08:08:11-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Problem with LINK
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

This is because all the library string functions are lumped together
in a single .C file, so loading any one of them loads them all.  This
is a fuzzy area, because while in the past it used to be possible to
have local definitions take the place of library ones, the ANSI draft
mandates that this is not possible -- any reference to a standard library
function must get exactly that function.  I can see pros and cons either
way.  The simplest (and most portable) solution is to use some different
name for your local flavor of rindex (which by the way is not going to
be a standard library function -- this is just a synonym for strrchr).
-------
24-Mar-87 08:23:31-PST,1142;000000000001
Mail-From: KLH created at 24-Mar-87 08:13:29
Date: Tue 24 Mar 87 08:13:23-PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Command line expansion of wildcards
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

You are correct that on UNIX the shell is responsible for wildcard
expansion (as well as for I/O redirection and argument vector setup).
The default KCC program startup attempts to emulate this behavior to
a limited extent, and including wildcard expansion makes sense.

However, there ARE programs which don't want this default behavior, and
we have provided a way for them to avoid it.  The NIC "whois" program,
for example, is written in C, yet its command line input must avoid
doing funny things with the funny characters it accepts (such as * and ! and
so forth).  It does this with an #include <urtsud.h>.  The default
definitions in this file avoid the shell-like parsing.

Looks like this is something that through oversight was not documented
in CC.DOC.  It will be.
-------
 4-Apr-87 11:32:06-PST,1185;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Sat 4 Apr 87 11:23:06-PST
Date: Sat, 4 Apr 1987  14:19 EST
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: realloc() bug

Symptom:
	Using realloc() to shrink the size of a block returns garbage.

Diagnosis:
	The code did the split() correctly but forgot to put the old
	pointer where it would be passed back to the user. 

Fix:

;COMPARISON OF SRC:<KCC.LIB>MALLOC.C.185 AND SRC:<KCC.LIB>MALLOC.C.186
;OPTIONS ARE    /3

**** FILE SRC:<KCC.LIB>MALLOC.C.185, 8-47 (14868)
    else if (old->size > need)		/* if reducing, free the tail */
	split(old, need);
**** FILE SRC:<KCC.LIB>MALLOC.C.186, 8-47 (14868)
    else if (old->size > need) {	/* if reducing, free the tail */
	split(old, need);
	return ptr;
    }
***************

**** FILE SRC:<KCC.LIB>MALLOC.C.185, 8-56 (15211)
    }
    return new;				/* return updated char pointer */
**** FILE SRC:<KCC.LIB>MALLOC.C.186, 8-58 (15233)
	return new;			/* return updated char pointer */
    }					/* never get here */
***************

--Rob
 9-Apr-87 19:37:50-PDT,339;000000000001
Mail-From: IAN created at  9-Apr-87 19:35:45
Date: Thu 9 Apr 87 19:35:40-PDT
From: Ian Macky <[email protected]>
Subject: Re: realloc() bug
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Thanks for the bugfix...

--ian
-------
18-Apr-87 19:55:45-PDT,1938;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Sat 18 Apr 87 19:43:26-PDT
Date: Sat, 18 Apr 1987  22:44 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: ADJSP 17,1 in the middle of a function call?

I could probably get this down to a smaller example, but I have to get
back to work.

I haven't updated my sources for a couple of weeks, you may have fixed
this without me knowing it.

--Rob

================================================================
C code:
================================================================
static int udpiqh;

int udp_recv(p, bsize, waitp)
    char *p;
    int bsize;
    int waitp;
{
    int err;
    if((err = udp_jsys((waitp? udpiqh: udpiqh|1),*(int *)p)) != 0)
	logpkt(p);
    return(err);
}
================================================================
Fail code:
================================================================
	TITLE	kccbug
	.REQUEST C:LIBc.REL
	$$CVER==<2,,1>
	INTERN $$CVER
	OPDEF ADJBP [IBP]
DEFINE %CHRBP(A,M)
<	SETO A,
	ADJBP A,M
>
IFNDEF ERJMP,< OPDEF ERJMP [JUMP 16,] >
OPDEF ERJMPA [ERJMP]
OPDEF	XMOVEI	[SETMI]
	DEFINE IFIW <SETZ >
XBLT==<020000,,0>
	TWOSEG	400000	
	RELOC	0	
	RELOC	400000	
	DEFINE %%CODE <RELOC>
	DEFINE %%DATA <RELOC>
PURGE IFE,IFN,IFG,IFGE,IFL,IFLE,IFDEF,IFNDEF,IFIDN,IFDIF

	%%DATA
udpiqh:	BLOCK	1

	%%CODE
udp.re:
	MOVE 4,-1(17)
	TLZ 4,$$BPPS
	PUSH 17,0(4)
	SKIPN 5,-4(17)
	 SKIPA 3,udpiqh
	 SKIPA 3,udpiqh
	 IORI 3,1
	ADJSP 17,1		; Huh????
	PUSH 17,3
	PUSHJ 17,udp.js
	ADJSP 17,-2
	MOVEM 1,0(17)
	JUMPE 1,$1
	PUSH 17,-2(17)
	PUSHJ 17,logpkt
	ADJSP 17,-1
$1==.
	POP 17,1
	POPJ 17,

$$CPKI==0
	INTERN $$CPKI
$$CPKA==0
	INTERN $$CPKA

	LIT
	EXTERN	$$BPPS
	EXTERN	$$$CPU
	EXTERN	$$$CRT
	INTERN	udp.re
	EXTERN	udp.js
	EXTERN	logpkt
	END
11-May-87 18:19:03-PDT,525;000000000001
Mail-From: KLH created at 11-May-87 18:17:50
Date: Mon 11 May 87 18:17:42-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: ADJSP 17,1 in the middle of a function call?
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

This bug is now fixed by the new version (561).  It was a real pain,
otherwise it would have been fixed sooner -- was busy with other things.
Next bug, please...
-------
22-May-87 03:30:16-PDT,1242;000000000001
Mail-From: KLH created at 22-May-87 03:24:47
Date: Fri 22 May 87 03:24:45-PDT
From: Ken Harrenstien <[email protected]>
Subject: KCC vs Fail/Macro, round 69
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

Make that LINK too.  It turns out that the command line scanners for
FAIL, MACRO, and LINK have no (none, null, zilch) way to quote filename
chars.  If your filename contains anything but alphanumerics or is longer
than 6 characters, you're out of luck.  I always sort of suspected this,
but was too lazy to go look up the proper quote mechanism or whatever.
I just tried, and verified (by examining the source code) that no such
ability exists.

MIDAS, of course, has enough cleverness.  But LINK still doesn't.

This causes problems for much stuff written on UNIX which is sometimes
made of modules with names like mod_thisfunct.c.

I suppose we could painfully rename everything when importing stuff.
This probably will help in porting to other crippled systems like
those on PCs, etc. which can't handle longer filenames.  But I can't
help wondering if there might not be some clever way to avoid this, or
do it automatically, or something... any ideas?
-------
27-May-87 01:26:02-PDT,970;000000000001
Received: from BIONET-20.ARPA by SRI-NIC.ARPA with TCP; Wed 27 May 87 01:14:45-PDT
Date: Wed 27 May 87 00:58:03-PDT
From: The Mailer Daemon <[email protected]>
To: [email protected]
Subject: Message of 27-May-87 00:57:59
ReSent-Date: Wed 27 May 87 01:14:29-PDT
ReSent-From: David Roode <[email protected]>
ReSent-To: [email protected]
ReSent-Message-ID: <[email protected]>

Message failed for the following:
[email protected].#Internet: Can't forward - unknown host "SRI-NIC"
	    ------------
Date: Wed 27 May 87 00:57:59-PDT
From: David Roode <[email protected]>
Subject: KCC Libraries
To: [email protected], [email protected]
cc: [email protected]
Phone: (415) 962-7322
Message-ID: <[email protected]>

1)  Is there a screen management, forms, or display package for
KCC?

2)  Is there a sharable runtime segment such as SAIL or PASCAL
has for KCC?
-------
-------
28-May-87 09:46:15-PDT,819;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Thu 28 May 87 09:45:54-PDT
Date: Thu, 28 May 1987  12:45 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: MIDAS libraries for KCC

This isn't a bug, but the list goes to the right people.

I have some MIDAS code sitting on XX (in SRC:<KCC.MIDAS>) which
can be linked with KCC code.  Most useful of these modules is an
interface to the HAKINQ library, so that C programs have full access
to the INQUIR database.

Some of the code needs other files in MID: (eg, MACSYM).

I find this stuff useful (it'd be more useful if the MIDAS code it
invokes would run in non-zero sections, but that's life).  Help
yourselves if you want it.

--Rob
 2-Jun-87 23:55:55-PDT,1580;000000000001
Mail-From: KLH created at  2-Jun-87 23:40:52
Date: Tue 2 Jun 87 23:40:50-PDT
From: Ken Harrenstien <[email protected]>
Subject: New plan for signal() and BSD sigvec()
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

I have been wrestling with various ideas on how to most satisfactorily
implement the 4.3BSD Unix sigvec() mechanism (which includes the old
V7 signal() as a subset).  The existing signal code in the KCC library
is only a partial implementation and has several deficiencies, e.g. only
one signal can be handled at a time, and the "system calls" cannot return
EINTR; moreover, their data structures can be horribly messed up.

The details of the scheme I came up with are too long to relate in this
message, particularly when I'm not sure who has an interest in the outcome.
If you would like to read my current thinkpiece and comment on it, the
file is PS:<KLH>SIGNAL.PLAN on SRI-NIC.ARPA and should be accessible via
anonymous FTP.

A brief summary: I propose to have all PSIs at a single level, and
have the PSI handler do DEBRK%s as quickly as possible after adjusting
various global masks and variables.  No signal handler will run at
interrupt level.  All features of the V7 and BSD scheme can be
implemented, including signal masks and many independent handlers.
The primary difficulty is having no obvious way to transparently
resume execution of a user-code JSYS interrupted by a signal.

If this interests (or worries) you, please read the file and send
comments!

--Ken
-------
17-Jun-87 23:06:59-PDT,727;000000000001
Mail-From: KLH created at 17-Jun-87 22:53:57
Date: Wed 17 Jun 87 22:53:55-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: kcc bug
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

OK, I've installed a new version (564) that should fix your problem.
Unsigned division was getting confused in the rare case (which you
somehow generated) where the divisor address used a register that the
division was about to clobber (i.e. when trying to simulate something
like IDIV R,(R+1)).  I put in a new code sequence that avoids this and
is even a little faster, though still unavoidably clumsy.
-------
18-Jun-87 20:46:11-PDT,1265;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Thu 18 Jun 87 20:41:31-PDT
Date: Thu, 18 Jun 1987  21:40 MDT
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: Need help, please

     I have been trying to port what I thought was a fairly simple
pair of programs from the Unix world to this machine, called compress.
I got one side to work: uncompress, with a minimum of effort, and it
is the far more complex of the two programs.  Both programs were the
basis of the MSDOS ARC program I ported successfully last year.  In
fact, much of the code is identical, which is why the uncompress went
so smoothly.  However, the compress has me stymied: I cannot see why
it doesn't produce identically compressed files that the Unix version
produces.  In fact, it produces files larger than the original!
     So, I'm looking for some fresh eyes to spot something obvious
that I've overlooked.  I have everything available: the TOPS20
conditionalized source with the original code left intact, the section
of code which successfully implements the same algorithm in the ARC
program, and the sample test file.  Any takers?

--Frank
18-Jun-87 22:46:09-PDT,753;000000000001
Mail-From: KLH created at 18-Jun-87 22:43:27
Date: Thu 18 Jun 87 22:43:23-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Need help, please
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Hmmm.  Recently I ported a program called "compress" in order to unpack
the Gnuemacs tar distribution file.  This program includes both compression
and uncompression, so it doesn't sound like exactly the same thing you
have.  I haven't tested it on compression, being too busy with other
things, but perhaps you would like to make a fresh start using this
program (the most recent timestamp on it is 1/10/86).
-------
19-Jun-87 10:00:52-PDT,688;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Fri 19 Jun 87 09:47:51-PDT
Date: Fri, 19 Jun 1987  10:44 MDT
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   Ken Harrenstien <[email protected]>
Cc:   [email protected], [email protected]
Subject: Need help, please
In-reply-to: Msg of 18 Jun 1987  23:43-MDT from Ken Harrenstien <KLH at SRI-NIC.ARPA>

Ken,
     It's the same program.  I picked up my source from ucbvax and
from prep and compared the two - only very insignificant (for our
environment) differences.  I'd like to see your version.  Please send
me a pointer to the source.

Thanks,
Frank
22-Jun-87 14:04:43-PDT,424;000000000001
Received: from Score.Stanford.EDU by SRI-NIC.ARPA with TCP; Mon 22 Jun 87 13:53:22-PDT
Date: Mon 22 Jun 87 12:43:13-PDT
From: Peter Samson <[email protected]>
Subject: simptrcnv
To: [email protected]
Message-ID: <[email protected]>

Glancing at the definition of simptrcnv in CCOUT.C, I notice a number of
calls to fprintf that lack a file-pointer argument.  Is this a bug?
-------
22-Jun-87 15:22:07-PDT,505;000000000001
Mail-From: KLH created at 22-Jun-87 15:16:34
Date: Mon 22 Jun 87 15:16:19-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: simptrcnv
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Right; fixed.  Fortunately (or unfortunately?) that code only applies to
machines without extended addressing, which is why nothing stumbled across
it before, I guess.
-------
 1-Jul-87 07:06:14-PDT,708;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Wed 1 Jul 87 06:57:37-PDT
Date: Wed, 1 Jul 1987  07:57 MDT
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: Appending redirection

CC.DOC says that the ">>file" on the command line will append stdout
to an old file.  It should also create the file if it doesn't exist,
according to the man page on sh.  As you have it documented, it does
complain if the file doesn't exist.  However, if the file does exist,
it doesn't append stdout to it either.  stdout out appears to go no
where, and with no warning message...

--Frank
 6-Jul-87 20:39:14-PDT,1507;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Mon 6 Jul 87 20:35:03-PDT
Date: Mon, 6 Jul 1987  23:33 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: Any advice?

about what to do when I get a message

	malloc(): bad block on freelist

then fall into abort()?

IWBNI _free_list() and _memory_map() could run with a bad freelist so
that I could see exactly what -is- wrong with the freelist.

I've been debugging under IDDT and WINDOW, so I can show you what the
memory map looks like:

;address space
Entry vector location $$STRT, length 2

 -- Section 0   R W X  Private --
0-2         Private  R W X 
 -- Section 1   R W X  Private --
1000-1002   Private  R W X 
1005-1014   Private  R W X 
1015-1105   CHIVES.EXE.245 (11-101)  R X C 
1106        Private  R W X 
1400-1403   CHIVES.EXE.245 (103-106)  R X C 
1404        Private  R W X 
1405        CHIVES.EXE.245 (110)  R X C 
1406        Private  R W X 
1407-1447   CHIVES.EXE.245 (112-152)  R X C 
 -- Section 2   R W X  Private --
2000        Private  R X 
2001-2004   Private  R W X 
2006-2010   Private  R W X 
2777        Private  R X 
 -- Section 3   R W X  Private --
3000-3016   Private  R W X 

The malloc() space (sec 3) looks reasonable enough.  Is it normal for
there to be inpure pages scattered through section 1 like this?

Crash dump (BUGACS and all) available upon request.
 8-Jul-87 03:39:26-PDT,3607;000000000001
Mail-From: KLH created at  8-Jul-87 03:39:13
Date: Wed 8 Jul 87 03:39:08-PDT
From: Ken Harrenstien <[email protected]>
Subject: PID simulation plan
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

It turns out that the way getpid() worked wasn't quite right.  After
thinking about it for a while, here is the best scheme I have come up
with so far.  If no one points out any problems or better alternatives
this is what I'll do.

GETPID problems on T20/10X:

	TENEX has never had a notion of a unique process identifier,
except internally inside the monitor; this fork ID is simply not
accessible to the user.  Fork handles are all relative, in an obscene
attempt to prevent programs from referencing any process they
shouldn't.  This makes it impossible to truly implement getpid() as it
should be.  ITS does the right thing, of course; for ITS and T10
the PID is just the job (process) number.

PID values are generated by:
	(1) getpid() - self process ID.  This must not change over
		the lifetime of the process!
	(2) fork() - to identify the child process.
	(3) wait() - to identify the child process that stopped.
		This should match the value returned by fork().

PID values are used by:
	(1) kill() - to send signals to self, child, or parent.
		(It is rare to send them anywhere else.)
	(2) Code that checks the return value of wait().
	(3) Code that generates unique filenames, port numbers, or the like
		which should not conflict with those of any other
		active process.

Proposed scheme:
	T20 PID = <IPCF PID>,,<frk #><job #>
		<IPCF PID> - Left half of a PID generated by MUTIL% for .FHSLF.
			This is guaranteed by system to be unique.
		<frk #> - low 9 bits of relative fork handle, in 0777000.
		<job #> - low 9 bits of job number, in 0777.

	getpid() will remember the value generated on first call and
return that thereafter.  This satisfies the uniqueness and constancy
criterion, as well as being efficient.
	fork() and wait() will convert the resulting relative fork
handles to a child PID with a zero LH but with the other fields set.
Since relative fork handles are from 400000 to 400777, we only need
the low 9 bits.
	fork() will, in the new child process, copy the saved getpid()
value, if any; this is its parent's PID and may be used by kill().  The
saved value is then cleared so if the child calls getpid() it will generate
its own unique value.
	kill() checks its PID argument first against the saved
getpid() value to see if a signal is being sent to itself (.FHSLF).
If not it then sees whether it matches that of its parent (if any) and
sends a signal to .FHSUP if so.  Otherwise, if the LH is 0 it assumes
the signal is being sent to a child, and generates the appropriate
relative fork handle from the 9 bits in the PID value.  Note: There is
no good way to identify "miscellaneous" signals generated by another
process, unless the PSI channel triggered by IIC% is uniquely mapped.
	This scheme fails only if PIDs are somehow passed from one
process to another either via pipe, file, or vfork() shared memory, since
the result of a child's getpid() won't match what its parent's fork()
returned.  But this should practically never happen.

TENEX:
	On TENEX, which doesn't have IPCF, we just use GFRKS% to
locate our fork within the job fork structure and hope the resulting
number, which we stick in the LH, doesn't change (although it can).
At least TENEX doesn't have extended addressing either so we can munch
the GFRKS% data on the stack.
-------
 9-Jul-87 15:54:21-PDT,1407;000000000001
Received: from BIONET-20.ARPA by SRI-NIC.ARPA with TCP; Thu 9 Jul 87 15:41:26-PDT
Mail-From: GOLUB created at  8-Jul-87 11:07:44
Date: Wed 8 Jul 87 11:07:44-PDT
From: ELLIS E. GOLUB <[email protected]>
Subject: TERMINAL PAUSE and printf
To: [email protected]
cc: [email protected], [email protected]
Message-ID: <[email protected]>
ReSent-Date: Thu 9 Jul 87 09:58:08-PDT
ReSent-From: ELLIS E. GOLUB <[email protected]>
ReSent-To: [email protected]
ReSent-Message-ID: <[email protected]>

I have experienced strange behavior by a program which outputs to the 
terminal, when TERMINAL NO PAUSE END-OF-PAGE is in effect. Under 
these conditions, some output is lost, while output from later 
sections of the program begins inappropriately early. The same program
and data produce perfect output when the TERMINAL PAUSE option is 
used. Initially, the output was generated by printf("\n..... 
statements. When these gave poor results, I tried the \n at the end
of the line. When this failed, I tried fprintf(stdout,"...., and when 
that failed, I tried sprintf(buffer,".... followed by 
printf("%s\n",buffer). All of these attempts gave similar results.

Has anyone experienced similar problems, or does anyone have a fix 
that eliminates this annoying bug? 

				Ellis Golub
				U. Penn.
				(215) 661-3269

-------
 9-Jul-87 16:54:20-PDT,1158;000000000001
Mail-From: KLH created at  9-Jul-87 16:44:25
Date: Thu 9 Jul 87 16:44:23-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: TERMINAL PAUSE and printf
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

	Well, as I mentioned in my last message, I think the BIONET
people will have to handle this one.  I don't think it is a problem
with the code at all, unless that version of KCC still uses SOUTR%
instead of SOUT%.  An even older version had some problems with
sending lots of extraneous NUL characters.  These are the only things
I could imagine that might possibly make a difference depending on
whether page mode is in effect.
	Otherwise, it's a BIONET system problem, or a problem with
transmission of data to your terminal.  Even if it were a KCC problem,
there's nothing I can do about it -- BIONET would need to install a
more recent KCC to fix it.  Rusch, Relph, and Dautricourt at BIONET
appear to be the relevant KCC-cognizant people, so you'll have to bug
them.  Sorry I can't be of more help.
-------
13-Jul-87 15:46:53-PDT,3495;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Mon 13 Jul 87 15:40:39-PDT
Date: Mon, 13 Jul 1987  18:42 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
Subject: MALLOC.C changes

Here's a SRCCOM of the changes I've made to MALLOC.C.  One of them
(the second and third differences in this listing) is a bugfix I
reported some time ago, the others are to provide better support for
tracking down bad blocks in the freelist.

--Rob

;COMPARISON OF SRC:<KCC.LIB>MALLOC.C.185 AND SRC:<KCC.LIB>MALLOC.C.187
;OPTIONS ARE    /3

**** FILE SRC:<KCC.LIB>MALLOC.C.185, 3-43 (4875)
	    fputs("malloc(): bad block on freelist\n", stderr);
**** FILE SRC:<KCC.LIB>MALLOC.C.187, 3-43 (4875)
	    fprintf(stderr, "malloc(): bad block on freelist (%06o,,%06o)\n",
		    ((unsigned)old)>>18, ((unsigned)old)&0777777);
***************

**** FILE SRC:<KCC.LIB>MALLOC.C.185, 8-47 (14868)
    else if (old->size > need)		/* if reducing, free the tail */
	split(old, need);
**** FILE SRC:<KCC.LIB>MALLOC.C.187, 8-47 (14936)
    else if (old->size > need) {	/* if reducing, free the tail */
	split(old, need);
	return ptr;
    }
***************

**** FILE SRC:<KCC.LIB>MALLOC.C.185, 8-56 (15211)
    }
    return new;				/* return updated char pointer */
**** FILE SRC:<KCC.LIB>MALLOC.C.187, 8-58 (15301)
	return new;			/* return updated char pointer */
    }					/* never get here */
***************

**** FILE SRC:<KCC.LIB>MALLOC.C.185, 10-6 (16474)
**** FILE SRC:<KCC.LIB>MALLOC.C.187, 10-6 (16585)
#ifndef dbgfil
#define dbgfil	stderr
#endif
***************

**** FILE SRC:<KCC.LIB>MALLOC.C.185, 10-10 (16518)
    if (!free_head) printf("    ---- freelist is empty ----\n");
    else {
	printf("    ---- free-list ----\n");
	p = free_head;
	while (p) {
	    printf("    %o: %d.\n", p, p->size);
**** FILE SRC:<KCC.LIB>MALLOC.C.187, 10-14 (16678)
    if (!free_head) fprintf(dbgfil, "    ---- freelist is empty ----\n");
    else {
	fprintf(dbgfil, "    ---- free-list ----\n");
	p = free_head;
	while (p) {
	    fprintf(dbgfil, "    %o: %d.\n", p, p->size);
***************

**** FILE SRC:<KCC.LIB>MALLOC.C.185, 10-28 (16850)
    printf("Top block = %o\n", z);
    printf("Free head = %o\n", free_head);
    if (*z) puts("-- Memory map of malloc area --\n");
    while (*z) {			/* if zero, assume EOM */
	printf("%6o: ", z);
**** FILE SRC:<KCC.LIB>MALLOC.C.187, 10-32 (17037)
    fprintf(dbgfil, "Top block = %o\n", z);
    fprintf(dbgfil, "Free head = %o\n", free_head);
    if (*z) fprintf(dbgfil, "-- Memory map of malloc area --\n");
    while (*z) {			/* if zero, assume EOM */
	fprintf(dbgfil, "%6o: ", z);
***************

**** FILE SRC:<KCC.LIB>MALLOC.C.185, 10-38 (17145)
		printf("IN_USE\tsize = %o\tabove = %o\n",
**** FILE SRC:<KCC.LIB>MALLOC.C.187, 10-42 (17370)
		fprintf(dbgfil, "IN_USE\tsize = %o\tabove = %o\n",
***************

**** FILE SRC:<KCC.LIB>MALLOC.C.185, 10-43 (17274)
		printf("FREE\tsize = %o\tprev = %o\tnext = %o\n",
**** FILE SRC:<KCC.LIB>MALLOC.C.187, 10-47 (17508)
		fprintf(dbgfil, "FREE\tsize = %o\tprev = %o\tnext = %o\n",
***************

**** FILE SRC:<KCC.LIB>MALLOC.C.185, 10-48 (17421)
		printf("Bad header value, not FREE or IN_USE: %o\n", p->flag);
**** FILE SRC:<KCC.LIB>MALLOC.C.187, 10-52 (17664)
		fprintf(dbgfil, "Bad header value, not FREE or IN_USE: %o\n", p->flag);
***************

15-Jul-87 06:47:20-PDT,2703;000000000001
Received: from seismo.CSS.GOV by SRI-NIC.ARPA with TCP; Wed 15 Jul 87 06:44:36-PDT
Received: from uunet.UU.NET by seismo.CSS.GOV (5.54/1.14) 
	id AA01756; Wed, 15 Jul 87 09:46:00 EDT
Received: from enea.UUCP by uunet.UU.NET (5.54/1.14) with UUCP 
	id AA15950; Wed, 15 Jul 87 09:45:52 EDT
Received: by enea.se (5.57/1.38)
	id AA07135; Wed, 15 Jul 87 15:00:40 +0200 (MET)
Received: from LISBET (lisbet.liu.se) by majestix.liu.se; Wed, 15 Jul 87 14:50:18 +0200
Received: from FREJA (not validated) by LISBET; Wed 15 Jul 87 14:48:33
Received: from ATHENA (not validated) by FREJA; Wed 15 Jul 87 14:48:07
Received: from AIDA by ATHENA with Cafard; Wed 15 Jul 87 14:46:14
Date: Wed 15 Jul 87 14:39:21
From: Per-Erik Martin <[email protected]>
Subject: KCC-3 bug
To: [email protected]
Message-Id: <870715143921.6.P-E-MARTIN@AIDA>


  Hi!

We are running KCC-3 on TOPS-20 v6.1.
I stumbled over what seems to be a bug in the code generator, which can
repeated by running the small program included at the end of this letter.

Another question : I keep CC.EXE in a separate directory from the libraries
and includes (keeping SYS: as short as possible). When loading a C-program,
LINK opens LIBC.REL for reading several times. The problem is that it
insists on having a LIBC.REL in the directory where CC.EXE is located,
probably due to some hardwired directory number. It does always opens
C:LIBC.REL, though. I can not guarantee that it is not my own fault (I may
have failed to build LIBC correctly) or some stupidity in LINK (very
possible). Or is this a known problem?


If this is old news, please ignore them.


Per-Erik Martin
Computing Science Dept.,
Uppsala University
Box 520
S-721 20 Uppsala
Sweden
(Email: [email protected])


------------------------------------------------------------
/* This little function originally appeared in an extremely hairy
   Phase-Of-the-Moon program. */

#include <stdio.h>
#define ZIP 42
#define ZAP 666

int Foo(x)			/* This does not work. */
  double x;
{
  register int i;
  i = x * ZIP + 0.5;
  if ((i += ZIP + ZAP) < 1)	/* Overoptimized around here, I think. */
    i = 1;
  return(i);
}

int Bar(x)			/* This works. */
  double x;
{
  register int i;
  i = x * ZIP + 0.5;
  printf("");			/* Added dummy statement. */
  if ((i += ZIP + ZAP) < 1)
    i = 1;
  return(i);
}

main()
{
  register double h;
  h = 0.0001;
  printf("Foo called with  %f returns %d, which is wrong.\n", h, Foo(h));
  printf("Bar called with  %f returns %d, which is correct.\n", h, Bar(h));
  exit(0);
}
------------------------------------------------------------
-------
16-Jul-87 00:32:24-PDT,1556;000000000001
Mail-From: KLH created at 16-Jul-87 00:22:46
Date: Thu 16 Jul 87 00:22:36-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: KCC-3 bug
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <870715143921.6.P-E-MARTIN@AIDA>
Message-ID: <[email protected]>

Thanks for the bug note.  It is indeed an optimization bug which
is still tickled in the latest version; it is a little hairy and will
take some time (next week?) to determine the simplest fix.

As for the LIBC problem, I suggest installing and using the FAIL
assembler that comes with KCC.  It has code to treat logical names in
.REQUEST filenames as logical names rather than remembering the
directory number, so you can change your definition of C: later and
still have things work as you expect.  It's possible that MACRO may
not do this; that is, it may determine the C: directory number at
assembly time and store that in the .REL file (ugh!).  I haven't looked
at it to make sure.  If your C: now is different from your C: at the
time you built the library, you may have problems.  This can be fixed
by rebuilding the library.

The future fix for this is likely to be a complete removal of the .REQUEST
pseudo, so that loading must be done either by invoking KCC or by manually
specifying C:LIBC to LINK.  This will avoid the problem you're having, as
well as other more obscure problems.

The LINK that comes with v6.1 is pretty gross, but it isn't the problem
here (as far as I know).
-------
16-Jul-87 20:36:31-PDT,781;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Thu 16 Jul 87 20:22:23-PDT
Date: Thu, 16 Jul 1987  23:09 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
Subject: FYI

I eventually found the problem that was trashing the freelist.  It was
my bug, not yours.  I was doing

	ipcf_buffer = malloc((npages+1)*PAGE_SIZE);

instead of

	ipcf_buffer = malloc((npages+1)*PAGE_SIZE*sizeof(int));

which did unpredictable and destructive things to memory when I
started using paged IPCF to create and destroy pages in that area.

I do suggest you use the changes I made to MALLOC.C, the problem was
much easier to spot once I could do a readable dump of the dynamic
memory state.

--Rob
19-Jul-87 13:21:24-PDT,803;000000000001
Mail-From: KLH created at 19-Jul-87 13:19:30
Date: Sun 19 Jul 87 13:19:27-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: KCC-3 bug
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <870715143921.6.P-E-MARTIN@AIDA>
Message-ID: <[email protected]>

OK, I've found and fixed the bug.  The new version of KCC has been
installed here as SYS:CC.EXE, as usual.  This may not help you if you
have no way to FTP such files, but fortunately the bug is quite rare
and difficult to tickle, plus you can always compile without
optimization if you suspect the optimizer is making a mess of things.

The library upgrade (for CARM v2) is almost done, so it shouldn't be long
before we have another distribution ready.
-------
30-Jul-87 06:09:22-PDT,1170;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Thu 30 Jul 87 06:07:28-PDT
Date: Thu, 30 Jul 1987  09:08 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: So, you guys only use GENERATION-RETENTION-COUNT == 1, huh?

[PHOTO:  Recording initiated  Thu 30-Jul-87 8:58AM]

 MIT TOPS-20 Command Processor 5(312160)-2
XX>ty t.c
#include <stdio.h>
main(argc,argv)
    int argc;
    char *argv[];
{
    int i;
    for(i = 0; i < argc; ++i)
	printf("argv[%d]=\"%s\"\n",i,argv[i]);
}
XX>v -oa

   XX:<SRA>
 -OA.CMD.1;P777700          1 1058(7)    15-Jun-87 02:00:41 SRA       
      .2;P777700            1 224(7)     15-Jun-87 23:55:51 SRA       
   .FLUSH-LIST.2;P777700    1 1098(7)    15-Jun-87 01:56:28 SRA       
      .3;P777700            1 1109(7)    15-Jun-87 23:54:24 SRA       

 Total of 4 pages in 4 files
XX>t.exe -oa.*.*
argv[0]="T"
argv[1]="XX:<SRA>-OA.CMD"
argv[2]="XX:<SRA>-OA.CMD"
argv[3]="XX:<SRA>-OA.FLUSH-LIST"
argv[4]="XX:<SRA>-OA.FLUSH-LIST"
XX>pop

[PHOTO:  Recording terminated  Thu 30-Jul-87 8:59AM]
30-Jul-87 11:09:24-PDT,774;000000000001
Mail-From: IAN created at 30-Jul-87 11:04:41
Date: Thu 30 Jul 87 11:04:12-PDT
From: Ian Macky <[email protected]>
Subject: No version# in expansion of wild filespecs
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

I updated _namew() in URT.C to include the version# of the files.  Here's
the change:


;COMPARISON OF SS:<C.LIB.USYS>URT.C.111 AND SS:<C.LIB.USYS>URT.C.112
;OPTIONS ARE    /3

**** FILE SS:<C.LIB.USYS>URT.C.111, 16-14 (22572)
    ablock[3] = 0111100000001;	/* DEV+DIR+NAME+TYPE, punctuate */
**** FILE SS:<C.LIB.USYS>URT.C.112, 16-14 (22572)
    ablock[3] = 0111110000001;	/* DEV+DIR+NAME+TYPE+VERS, punctuate */
***************

-------
12-Aug-87 07:15:21-PDT,2561;000000000001
Received: from uunet.UU.NET by SRI-NIC.ARPA with TCP; Wed 12 Aug 87 06:46:59-PDT
Received: from enea.UUCP by uunet.UU.NET (5.54/1.14) with UUCP 
	id AA25368; Wed, 12 Aug 87 09:46:31 EDT
Received: by enea.se (5.57/1.39)
	id AA07203; Wed, 12 Aug 87 15:12:18 +0200 (MET)
Received: from LISBET (lisbet.liu.se) by majestix.liu.se; Wed, 12 Aug 87 14:58:01 +0200
Received: from FREJA (not validated) by LISBET; Wed 12 Aug 87 14:54:45
Received: from ATHENA (not validated) by FREJA; Wed 12 Aug 87 04:39:25
Received: from AIDA by ATHENA with Cafard; Wed 12 Aug 87 04:39:37
Date: Wed 12 Aug 87 04:26:59
From: Per-Erik Martin <[email protected]>
Subject: KCC-3 & Dhrystone
To: [email protected]
Message-Id: <870812042659.6.P-E-MARTIN@AIDA>


KCC fails compiling the Dhrystone benchmark program (version 1.1, latest
edition 1/6/86). DRY.C is 5 pages so I don't include it here and hope that
you get some clue from the logfile.
I get the same two warnings, regardless of optimization.
Normal values could be "...= 15" and "2242 dhrystones/second".
If you need any additional information (or DRY.C), tell me.


[PHOTO:  Recording initiated  Wed 12-Aug-87 3:45AM]

> cc -O=-all dry.c -o drynr.exe
KCC:	dry

Warning at Proc0+107, line 294 of dry.c:
Proc1(
Internal error - Register allocation: unreleased registers left over from previo
us code

Warning at Proc0+107, line 294 of dry.c:
Proc1(
Internal error - Register allocation: release of a spilled register
<P-E-MARTIN.DHRYSTONE>DRY.PRE.1
<P-E-MARTIN.DHRYSTONE>DRY.FAI.1
FAIL:  dry
LINK:	Loading
> 
> drynR.EXE.3 
Dhrystone(1.1) time for 50000 passes = 0
This machine benchmarks at 50000 dhrystones/second
> 
> cc -O=parse-gen-object dry.c -o drynr.exe
[...]
> 
> drynR.EXE.4 
Dhrystone(1.1) time for 50000 passes = 404728770
This machine benchmarks at 0 dhrystones/second
?Illegal instruction 6732 at 7
?Undefined operation code
> 
> cc -O=g-p-o dry.c -o drynr.exe
[...]
> 
> drynR.EXE.5 
Dhrystone(1.1) time for 50000 passes = 0
This machine benchmarks at 50000 dhrystones/second
> 
> cc -O=o-g-p dry.c -o drynr.exe
[...]
> 
> drynR.EXE.6 
Dhrystone(1.1) time for 50000 passes = 0
This machine benchmarks at 50000 dhrystones/second
> 
> cc -O=+all dry.c -o drynr.exe
[...]
> 
> drynR.EXE.7
Dhrystone(1.1) time for 50000 passes = 555731564
This machine benchmarks at 0 dhrystones/second
?Illegal instruction 6732 at 7
?Undefined operation code
> 
> pop

[PHOTO:  Recording terminated Wed 12-Aug-87 3:53AM]
-------
12-Aug-87 11:23:23-PDT,900;000000000001
Mail-From: KLH created at 12-Aug-87 11:15:07
Date: Wed 12 Aug 87 11:14:57-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: KCC-3 & Dhrystone
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <870812042659.6.P-E-MARTIN@AIDA>
Message-ID: <[email protected]>

You didn't say which version of KCC you were using, but that sounds like
a bug which was fixed a while ago.  The current binary available is version
568.

If you cannot get the new binary easily but still want to run that
program then you will either have to juggle the code in Proc0 (which
is where the error is happening) until it no longer produces that
message, or look at the assembler output file and correct it.

If you send me the source (just to me, not to BUG-KCC!) then I could
test it out here and mail you the results.

--Ken
-------
12-Aug-87 11:25:11-PDT,716;000000000001
Mail-From: KLH created at 12-Aug-87 11:21:57
Date: Wed 12 Aug 87 11:21:45-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: KCC-3 & Dhrystone
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <870812042659.6.P-E-MARTIN@AIDA>
Message-ID: <[email protected]>

Oh yeah, you did mention "KCC-3" so I assume we're talking about
version 558 which was the one included in that particular
distribution.  In this case, I'm pretty sure the bug has been fixed,
but there have been enough changes to the source that I don't think I
could easily mail you a srccom.  Is there some upper bound to the size
of messages you can receive?
-------
19-Aug-87 22:52:03-PDT,447;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Wed 19 Aug 87 22:42:02-PDT
Date: Wed, 19 Aug 1987  23:41 MDT
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: touch and fdate?

In your plans of handy utilities, might you already have equivalents
to touch and fdate?  (Fdate forces a particular datestamp.)

--Frank
20-Aug-87 08:47:43-PDT,3696;000000000001
Received: from SCIENCE.UTAH.EDU by SRI-NIC.ARPA with TCP; Thu 20 Aug 87 08:34:49-PDT
Date: Thu 20 Aug 87 09:33:46-MDT
From: "Nelson H.F. Beebe" <[email protected]>
Subject: Re: touch and fdate?
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
X-US-Mail: "Center for Scientific Computation, South Physics, University of Utah, Salt Lake City, UT 84112"
X-Telephone: (801) 581-5254
Message-ID: <[email protected]>

I don't have either.  In Sun OS 3.3 (~4.2BSD), fdate() is
only a Fortran routine for returning a date string.  Under
System V, touch can optionally set a file date/time.  The
Sun man page (which describes both BSD and SYS V versions)
is appended.   Touch is not a standard library function.
I'm just looking now at the source code under 4.3BSD, where
it says:
	if the file exists, read and write its first character.
	if the file doesn't exist, create it, unless -c
		option prevents it.
	if the file is read-only, -f forces chmod'ing and touch'ing.

Because of variable bytesizes and SOS line numbers in
TOPS-20 files, a read/write sequence is probably not
advisable.  Better to do a CHFDB% instead; that avoids
mapping the file too.

It might be easiest to do all of this in PCL; ours has
Michel Debar's nice jsys extensions which make it possible
to do limited systems programming in PCL.


TOUCH(1V)                USER COMMANDS                  TOUCH(1V)



NAME
     touch - update times of last access and  modification  of  a
     file

SYNOPSIS
     touch [ -c ] [ -f ] filename ...

SYSTEM V SYNOPSIS
     touch [ -c ] [ -a ] [ -m ] [ mmddhhmm[yy] ] filename ...

DESCRIPTION
     touch causes the access and modification times of each argu-
     ment to be set to the current time.  A file is created if it
     does not already exist.

     touch is valuable when used  in  conjunction  with  make(1),
     where,  for  instance,  you  might  want to force a complete
     rebuild of a program composed of many  pieces.   In  such  a
     case, you might type:
          % touch  *.c
          % make

     make would then see that all the .c files were  more  recent
     than  the corresponding .o files, and would start the compi-
     lation from scratch.

OPTIONS
     -c   Do not create filename if it does not exist.

     -f   Attempt to force the touch in spite of read  and  write
          permissions on filename.

SYSTEM V OPTIONS
     -a   Update only the access time.

     -m   Update only the modification time.

     mmddhhmm[yy]
          Update the times to the specified time rather  than  to
          the current time.  The first mm is the month, dd is the
          day of the month, hh is the hour, and the second mm  is
          the  minute;  if  yy  is  specified, it is the last two
          digits of the year, otherwise the current year is used.

SEE ALSO
     utimes(2), make(1)

BUGS
     It is difficult to touch a file whose name consists entirely
     of  digits  in  the System V touch, as it will interpret the
     first such non-flag argument as a  time.   You  must  ensure
     that  there is a character in the name which is not a digit,



Sun Release 3.2    Last change: 24 April 1986                   1






TOUCH(1V)                USER COMMANDS                  TOUCH(1V)



     by specifying it as ./name rather than name.






















































Sun Release 3.2    Last change: 24 April 1986                   2


-------
20-Aug-87 10:21:39-PDT,684;000000000001
Mail-From: KLH created at 20-Aug-87 10:18:58
Date: Thu 20 Aug 87 10:17:11-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: touch and fdate?
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Uh, those are not library functions.  Programs to do those functions can
be easily written however.  Note that the new library includes a
simulation of the Unix "utime" system call, which is used to set file
reference dates.  This is implemented using CHFDB.  It is small, so
if you need it before KCC-4 is ready, we can mail you the routine.
-------
22-Aug-87 13:52:42-PDT,709;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sat 22 Aug 87 13:49:08-PDT
Date: Sat, 22 Aug 1987  14:48 MDT
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   Ken Harrenstien <[email protected]>
Cc:   [email protected], [email protected]
Subject: touch and fdate?
In-reply-to: Msg of 20 Aug 1987  11:17-MDT from Ken Harrenstien <KLH at SRI-NIC.ARPA>

Ken,
     My user, who requested the functionality of those programs, is
willing to wait as I am for KCC-4.
     Will you be including some TOPS-20 equivalent utility
programs/packages similar to these programs, and Nelson's make, as
part of the KCC distribution?

--Frank
22-Aug-87 15:07:40-PDT,768;000000000001
Mail-From: KLH created at 22-Aug-87 15:01:25
Date: Sat 22 Aug 87 15:01:23-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: touch and fdate?
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

I wasn't planning to include utility programs, since it's hard enough just
keeping KCC and LIBC straight.  "make" in particular is a non-trivial
package.  It does make sense though (especially for people who get this
stuff via tape).  We won't scour around looking for stuff, but if someone
sends in an utility that doesn't require lots of special-casing, we can
include it.

I'll check with Nelson on the status of make...
-------
24-Aug-87 14:07:42-PDT,2287;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Mon 24 Aug 87 13:54:05-PDT
Date: Mon, 24 Aug 1987  16:53 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
Cc:   [email protected], [email protected]
Reply-To: [email protected]
Subject: Problems building CHIVES...

[Bug list address fixed]

    Date: Mon 24 Aug 87 15:59:52-EDT
    From: [email protected]

      I copied everything over from XX and attempted to build a CHIVES of my own...
    The following problems were encountered:

        1) <CHIVES.INCLUDE>MONSYM.CTL did not work as distributed. This was a
           minor problem - the PCL assumed that DSK: was defined as part of SYS:,
           so it didn't work when it wasn't. The solution is to adda line with
           "@define sys: dsk:,sys:" to CHIVES.CTL.

Fixed.

        2) Modules UDP20X.C and IPCF.C do not compile on my system. This is a more
           major problem in that KCC dies with an "?Out of memory" error while
           reading MONSYM.H. This seems strange given that my MONSYM.H comes out to
           only 43 pages. How do you have your KCC configured? Any suggestions on
           what I have to change in KCC to avoid this problem?

Oh, yeah.  KCC as distributed will always run out of memory when
reading MONSYM.H.  You have to link it with extended addressing.  I
copied the .CTL file I used to build CC.EXE to XX:<CHIVES>, I'll add a
mention of it to one of the -READ-.-THIS- files.  I enclose the .CTL
file below so you don't have to fire up another FTP just to snarf it.

I don't suppose I could talk the KCC people into making the
distributed CC.EXE run this way?  I didn't think so.

Thanks, Vince, you win the early bird award for first bug report.

--Rob

; CTLified version of [XX]SRC:<KCC.KCC>CC.MIC.24, with one change:
; "-i" is not standard (MONSYM.H will blow out non-extended compiler).
;@TERMINAL NO PAUSE END
;@PHOTO
;*CC.LOG
@CC -q -o=NCC -i -
@	CC CCASMB CCCODE CCCREG CCCSE CCDATA CCDECL CCDUMP CCERR -
@	CCEVAL CCFOLD CCGEN CCGEN1 CCGEN2 CCGSWI CCINP CCJSKP CCLAB -
@	CCLEX CCOPT CCOUT CCREG CCSTMT CCSYM CCTYPE
@VDIR NCC.EXE.0
;@POP
;@;TERMINAL PAUSE END
;@KMIC
24-Aug-87 14:36:54-PDT,747;000000000001
Mail-From: KLH created at 24-Aug-87 14:24:22
Date: Mon 24 Aug 87 14:24:19-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Problems building CHIVES...
To: [email protected], [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

The next distribution (KCC-4) will include a CCX.EXE in addition to
CC.EXE, as a convenience.  This is more important for people who don't
bother to keep the source files around, of course.

MONSYM is a real pain since 99% of the garbage in it is never used by
any particular compilation.  We've tried various ways to get around it
but nothing has really worked well yet.
-------
25-Aug-87 11:51:44-PDT,615;000000000001
Received: from C.CS.CMU.EDU by SRI-NIC.ARPA with TCP; Tue 25 Aug 87 11:40:23-PDT
Received: ID <[email protected]>; Tue 25 Aug 87 14:31:51-EDT
Date: Tue 25 Aug 87 14:31:49-EDT
From: [email protected]
Subject: Question about KCC/FAIL
To: [email protected]
Message-ID: <[email protected]>

By default, KCC uses FAIL and recommends that users do likewise. One problem
with this - how does one create universal files (for MONSYM et. al.) for FAIL's
use? Where does FAIL look for universal files and under what name? Are they
compatable with MACRO universal files?

	--Vince
-------
26-Aug-87 17:08:04-PDT,852;000000000001
Mail-From: KLH created at 26-Aug-87 16:55:29
Date: Wed 26 Aug 87 16:55:25-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Question about KCC/FAIL
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

FAIL's SEARCH pseudo looks for UNV:xxx.FUN -- basically where MACRO uses
*.UNV, FAIL uses *.FUN.  They aren't compatible.  It may work simply to
run FAIL on the MONSYM.MAC file; I'm not sure, as the copy of MONSYM.FUN
we have is a bit old.

The FAIL manual and source are included, so you have the same information
that we do.

You can configure KCC to use MACRO if you wish -- there is no real difference
except that MACRO takes a bit longer.  If you want to patch the binary
you can set TGASM to 1.
-------
 6-Sep-87 20:14:48-PDT,947;000000000001
Received: from C.CS.CMU.EDU by SRI-NIC.ARPA with TCP; Sun 6 Sep 87 20:12:17-PDT
Received: ID <[email protected]>; Sun 6 Sep 87 23:11:59-EDT
Date: Sun 6 Sep 87 23:11:56-EDT
From: [email protected]
Subject: Bug in MALLOC, version 185
To: [email protected]
Message-ID: <[email protected]>

There exists a rather sever bug MALLOC, version 185 which is part of LIBC,
version 124. The bug is in REALLOC - if a block is REALLOC'd for less space
than originally MALLOC'd, REALLOC will return garbage because the test for
this case fails to setup a valid return value. The following change will fix
the problem:

    else if (old->size > need) {	/*~~~ if reducing, free the tail */
	split(old, need);
	return ptr;			/*~~~ Return the proper pointer */
    } else {				/*~~~ bigger, so reallocate and copy */

"~~~" denotes the lines which are changed from the original source.

	Vince Fuller,
	CMU-CSD
-------
10-Sep-87 07:56:27-PDT,1221;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Thu 10 Sep 87 07:52:25-PDT
Date: Thu, 10 Sep 1987  10:47 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: could you make _doprnt() an extern rather than a static?

I'm revamping the buginf()/bughlt() routines for the 20x resolver.
It'd be real nice to be able to do something like

    if(foobar > FOOBAR_MAX)
	bughlt("main","the foobar parameter is too big (%o)",foobar);

When I mentioned this to a unix hacker, he said "Oh, yeah, I run into
that occasionally, just call _doprnt() directly".  Unfortunately, you
guys seem to believe that _doprnt() should be static.

Obviously, I can modify my local sources without much problem, but
this makes distribution of CHIVES a bit messy.  Would it be possible
to make _doprnt() a global routine so those of us who live near the
edge could use it?  The module in question is inherently non-portable
anyway (most of the code is for making Twenex crash dumps), although I
suspect that since you and I and 4.n BSD all use varargs.h this
particular routine would work fine under unix.

--Rob
10-Sep-87 10:01:28-PDT,970;000000000001
Mail-From: KLH created at 10-Sep-87 09:56:55
Date: Thu 10 Sep 87 09:56:50-PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: could you make _doprnt() an extern rather than a static?
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

There is a good reason why _doprnt is static.  It is non-portable,
non-documented, and non-necessary.  This is what the v{fs}printf
routines are for -- see page 337 of H&S (2nd ed), which even includes
an example of how to roll your own.

The new library supports all of the 2nd ed routines.  We are still
shaking it down; because it has one incompatibility (namely, the
size of a jmp_buf used by setjmp/longjmp), it can't be just installed
without some warning announcements.  The word is "any day now" -- as
soon as a day or two goes by without another bug crawling out to be
stomped.
-------
13-Sep-87 14:40:26-PDT,1145;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Sun 13 Sep 87 14:36:23-PDT
Date: Sun, 13 Sep 1987  17:19 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected], [email protected]
Subject: Cause found for CHIVES crashes on SUMEX and SIMTEL20

The whole thing was a wild goose chase.

SUMEX (and presumably SIMTEL20) has the KCCDIST: version of LIBC.REL,
which has several bugs in the MALLOC module (all of which I've long
since reported, I think).  In particular, there's a realloc() bug that
returns bad pointers; at several removes, this causes corruption of
the in-memory cache, eventually causing CHIVES to abort() when it
tries to cfree() the bogus pointer.

Mark, you should either snarf XX:SRC:<KCC.LIB>MALLOC.C.187, compile it
and MAKLIB it in, or just snarf XX:C:LIBC.REL if you don't want to
bother with sources.

Bug-KCC people: please fix the distributed LIBC.REL to have a working
realloc().  It's getting a little monotonous finding the same bug over
and over again.  Also, please add me to BUG-KCC@NIC.  Thanks.

--Rob
13-Sep-87 19:25:31-PDT,1286;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Sun 13 Sep 87 19:21:17-PDT
Date: Sun, 13 Sep 1987  22:14 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
Cc:   [email protected]
Reply-To: [email protected]
Subject: New stuff in XX:<CHIVES.SOURCE>

Accumulation of minor changes to a few modules, some 6.1 fixes for
GTDOM, support for the new GD%STA flag in GTDOM, support for automatic
CHIVES crash dumps.  Relative names in zone files should work now.

$INCLUDE still doesn't work right (don't try it), but I think I know
what's wrong now and it should be cleared up within a few days.

Tasks currently in the pipe are improvements to the search path code
(including remote search paths), better BUGxxx() handling, runtime
selectable debug code, general cleanup.

NOTE: Several people have had problems with bad versions of the KCC
runtimes.  All the KCC runtime bugs I know about have been reported to
BUG-KCC, action on them is pending.  In the meantime, if you have
problems with CHIVES crashing with a message like
	free(): tried to free invalid block
you should get a copy of XX's runtimes (source in XX:SRC:<KCC.LIB*>,
binary in XX:C:LIBC.REL).

--Rob
13-Sep-87 23:45:33-PDT,957;000000000001
Mail-From: KLH created at 13-Sep-87 23:45:27
Date: Sun, 13 Sep 87 23:45:23 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Cause found for CHIVES crashes on SUMEX and SIMTEL20
To: [email protected], [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

OK, you're on BUG-KCC.

Note that KCCDIST: normally doesn't change once a source distribution
is put together.  The reason for this is to keep everything
consistent, and there are so many files now that it's hard to do.  The
most recent working stuff is always C:LIBC.REL and SYS:CC.EXE.

However, as noted in the KCC INSTAL.DOC file, those have some risk
associated.  In particular, the current LIBC is not compatible with
older versions.  I will be announcing the new version momentarily.
A complete new source distribution will follow later.
-------
16-Sep-87 19:14:38-PDT,390;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Wed 16 Sep 87 19:10:12-PDT
Date: Wed, 16 Sep 87 20:10:13 MDT
From: Frank J. Wancho <[email protected]>
Subject: Is Rob's malloc() fix in beta release?
To: [email protected]
cc: [email protected], [email protected]
Message-ID: <[email protected]>

Ken,
     Subject says it all.

--Frank
-------
16-Sep-87 19:59:36-PDT,418;000000000001
Mail-From: KLH created at 16-Sep-87 19:56:58
Date: Wed, 16 Sep 87 19:56:55 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Is Rob's malloc() fix in beta release?
To: [email protected], [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

It has every known bug fix to everything.
-------
17-Sep-87 14:19:53-PDT,389;000000000001
Received: from MATHOM.CISCO.COM by SRI-NIC.ARPA with TCP; Thu 17 Sep 87 14:15:40-PDT
Date: Thu 17 Sep 87 14:18:01-PDT
From: William Westfield <[email protected]>
Subject: new KCC bug - something not big enough...
To: [email protected]
Message-ID: <[email protected]>

The Current KCC can't #include <monsym.h> - it runs out of memory.

BillW
-------
17-Sep-87 14:39:54-PDT,469;000000000001
Mail-From: KLH created at 17-Sep-87 14:39:23
Date: Thu, 17 Sep 87 14:39:11 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: new KCC bug - something not big enough...
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

It's probably hopeless to expect non-extended KCC to ever work with
<monsym.h>.  Try using CCX instead.
-------
17-Sep-87 20:12:26-PDT,1705;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Thu 17 Sep 87 20:07:48-PDT
Date: Thu, 17 Sep 1987  21:06 MDT
Message-ID: <[email protected]>
From: [email protected]
To:   [email protected]
cc:   [email protected]
Subject: New KCC beta files

It sure does look like you've implemented many of the things I've been
waiting a long time to see.  I'm not finished trying out compiling all
those programs waiting in the queue.  I did try one package that had
come to the top of the queue, and it had a few problems, probably all
non-standard things, like not understanding "#if 0" which seems to be
the style some programmers use to comment out a section of code.

Another part has to do with how to define a string in the command line
to CC.  The specific case is a -DBIN=\"some-string\".  In the source,
the BIN is part of a struct definition, and the substitution falls
apart complaining about the backslash (taking it to be \134).  Should
I not be using the backslashes to quote the double-quotes, not just
not use the double-quotes at all?  (Specifics on request.)

Finally, the program would like to use a dir.h.  Will it ever be
possible to add that as part of the emulation?  I think that would be
the finishing touch.

BTW, the program package I'm trying to work with is CMDF (part of
MMDF) as a replacement for the ZSLAVE program we are currently
running.  ZSLAVE is written in SIMULA and is the *only* SIMULA program
we have with a buggy runtime library.  In other words, very difficult
to maintain and fix.  Something like CMDF would be a significant
improvement, if I can get it going without too much lobotomizing...

--Frank
17-Sep-87 20:22:23-PDT,1034;000000000001
Mail-From: KLH created at 17-Sep-87 20:20:14
Date: Thu, 17 Sep 87 20:20:10 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: New KCC beta files
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Hmm.  "#if 0" is legal syntax and we use it in lots of code here, for
just that purpose (commenting out long sections).  Either the problem
is something else, or your source file somehow found a bug.

I think just saying -DBIN="string" will work.  The runtime doesn't
apply all of the Unix shell parsing rules, so double-quotes aren't special;
the only special thing is space or tab.  For this reason you cannot include
a space or tab in the string; for that reason, it's possible that someday
double-quotes WILL be recognized.

<dir.h> would be handy.  I'm not sure how hard it would be, though.
We don't have any immediate plans for implementing it (sort of taking
a breather...)
-------
17-Sep-87 23:07:27-PDT,557;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Thu 17 Sep 87 23:06:06-PDT
Date: Fri, 18 Sep 1987  00:05 MDT
Message-ID: <[email protected]>
From: [email protected]
To:   [email protected]
cc:   [email protected]
Subject: how about popen() and pclose()

Is there a way to get at those functions?  We have PIP:... if that
helps.

BTW, there are some fairly simple changes to the EXEC to get it to
read its RESCAN buffer, if you want them...  Stolen from the NYU EXEC,
courtesy of Ittai Hershman.

--Frank
18-Sep-87 00:02:28-PDT,468;000000000001
Mail-From: KLH created at 17-Sep-87 23:59:45
Date: Thu, 17 Sep 87 23:59:41 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: how about popen() and pclose()
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

They could probably be written without too much trouble.  Sure, send along
the EXEC changes, they might be useful.
-------
18-Sep-87 14:27:05-PDT,1079;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Fri 18 Sep 87 14:23:23-PDT
Date: Fri, 18 Sep 1987  17:23 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
Subject: Low priority and seemingly silly request

At some point when you guys are real bored, please change the lines of
the form "#ifdef COMMENT" to "#if 0" or something equally unambiguous.
I have discovered a legitimate case where it is necessary to define a
macro named COMMENT and no other name will do.  I have been able to
work around the problem so far by paying attention to the order in
which #include's are done, but obviously this not something one wants
to depend upon.

In case you're curious, the application for which this is needed is
the macro package which allows a C program to share definition files
with an assembler program.  COMMENT /* stuff */ happens to do the
right thing in MACRO and FAIL, can be defined to do the right thing in
MIDAS, and will do the right thing in C if it's defined as a nop.
18-Sep-87 15:32:16-PDT,784;000000000001
Mail-From: KLH created at 18-Sep-87 15:30:58
Date: Fri, 18 Sep 87 15:30:54 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Low priority and seemingly silly request
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Hmmm.  The historical reason for "#ifdef COMMENT" is that #ifdef existed
before #if did, and consequently is/was more portable.  I don't care though
and agree the #if form is preferable.

I'm curious why you need to share a definition file, however.  Can you not
use #asm and make everything a .C source file?  This was the approach I
took when I overhauled the C runtime and library, and it has been quite
successful.
-------
18-Sep-87 16:02:16-PDT,1730;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Fri 18 Sep 87 15:58:41-PDT
Date: Fri, 18 Sep 1987  18:59 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   Ken Harrenstien <[email protected]>
Cc:   [email protected]
Subject: Low priority and seemingly silly request
In-reply-to: Msg of 18 Sep 1987  18:30-EDT from Ken Harrenstien <[email protected]>

You missunderstand, I didn't supply enough context.

The code in question is GTDOM.MAC (a module that is linked into the
TOPS-20 monitor) sharing symbols with a bunch of resolver modules
written in C.  The assembler macro package takes care of translating
"foo_bar" to "foo.bar".  These definition files are used for domain
query types, layout of the messages that are passed between GTDOM% and
the resolver, and anything else that is of interest to both parties.
Eg (to pick two passages that are short enough to include here):

COMMENT /* QCLASS */
BTUPLE(qc_table)
 TUPLE(QC_IN,		1,	"IN"		)
 TUPLE(QC_CS,		2,	"CS"		)
 TUPLE(QC_CH,		3,	"CH"		)
 TUPLE(QC_ANY,		255,	"*"		)
ETUPLE
CONST(QC_MAX,		3)

COMMENT /* Message RR header format */
BSTRUCT(u_rr_header)
    DWORD ( length      )
    DHALF ( type        )
    DHALF ( class       )
    DWORD ( ttl         )
ESTRUCT(u_rr_header,U_RHSIZE)

Some C modules insert these files more than once, with different macro
definitions, in order to construct string tables and the like.

The comment syntax here is obviously a total kludge, but it happens to
work, and I was more interested in results than good taste.

If you're interested in details, see XX:<CHIVES.SOURCE>DSYMS*.*, the
source files for the existing macro packages.
18-Sep-87 16:42:17-PDT,402;000000000001
Mail-From: KLH created at 18-Sep-87 16:40:38
Date: Fri, 18 Sep 87 16:40:34 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Low priority and seemingly silly request
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Ah, I see.  Thanks for the clarification...
-------
25-Sep-87 05:07:13-PDT,776;000000000001
Received: from SCIENCE.UTAH.EDU by SRI-NIC.ARPA with TCP; Fri 25 Sep 87 05:03:07-PDT
Date: Fri 25 Sep 87 06:03:24-MDT
From: Lon Willett <[email protected]>
Subject: top level static variables
To: [email protected]
Snail-Mail: Science Computer, 210 Physics South, U. of Utah, SLC, UT  84112
Telephone:  (801) 581-5252
Message-ID: <[email protected]>

Top level static variables seem to be treated like internals.  E.g.
"static int FooBarA, FooBarB" will give a "multiply defined symbol:
FOOBAR" error (iff the declaration is outside of any functions scope).

Isn't this incorrect?  I thought static variables were supposed to
generate local variables of the "$n" variety, wherever they are
declared.

--Lon Willett
-------
25-Sep-87 17:52:33-PDT,1083;000000000001
Mail-From: KLH created at 25-Sep-87 17:50:26
Date: Fri, 25 Sep 87 17:50:23 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: top level static variables
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

You are correct that top-level static variable names are output to the
assembler as-is, rather than as local $n-type labels.  This is even
documented in CC.DOC.  The main reason for this is to help debug
programs.

There are two options for "fixing" KCC.  One is to make all static
variables use $n labels.  The other is to have KCC check such variables
for 6-char monocase identity and do something appropriate for static
variables, while complaining informatively about external variables.
The latter is preferable, but is also harder to do and will take more
time to figure out a good way to do it.

In the meantime, you can #define those symbols to be something else
which is unique in the first 6 characters.
-------
27-Sep-87 10:22:00-PDT,568;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sun 27 Sep 87 10:18:46-PDT
Date: Sun, 27 Sep 1987  10:52 MDT
Message-ID: <[email protected]>
From: [email protected]
To:   [email protected]
cc:   [email protected]
Subject: echo mode fails on net connections

To demonstrate, run TSGTTY while TELNET'd back to your own host (or
come in through a TAC).  Echo mode is not turned off.  Also, if you
SET TRAP JSYS SFMOD, you will see that it is not called either, which
is probably the reason why it is not set...

--Frank
27-Sep-87 10:22:03-PDT,889;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sun 27 Sep 87 10:18:55-PDT
Date: Sun, 27 Sep 1987  11:07 MDT
Message-ID: <[email protected]>
From: [email protected]
To:   [email protected]
cc:   [email protected], [email protected]
Subject: net echo bug found

The problem is that under a 5.4 monitor, the line speeds are returned
as -1.  When any terminal parameter is attempted to be changed, the
first parameter to be changed is the line speed.  If it is -1, a
return of an error is immediately made and no further changes are
made.  As we expect to run 5.4 for several more months, would you
please consider some other technique or ordering?  Perhaps one
alternative would be to check to see if the user is requesting a speed
change of his own terminal, and simply skip such a request without
returning at that point.

--Frank
27-Sep-87 13:17:01-PDT,670;000000000001
Received: from SUMEX-AIM.STANFORD.EDU by SRI-NIC.ARPA with TCP; Sun 27 Sep 87 13:15:34-PDT
Received: from PANDA.COM by SUMEX-AIM.STANFORD.EDU with Cafard; Sun, 27 Sep 87 13:13:37 PDT
Date: Sun, 27 Sep 87 12:47:50 PDT
From: Mark Crispin <[email protected]>
Subject: Re: net echo bug found
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Postal-Address: 1802 Hackett Ave.; Mountain View, CA  94043-4431
Phone: +1 (415) 968-1052
Message-ID: <[email protected]>

I suggest an ERJMP .+1 since it's perfectly reasonable to have undefined
terminal speed (-1) for PTY's and network terminals.
-------
28-Sep-87 05:22:15-PDT,948;000000000001
Received: from Sierra.Stanford.EDU by SRI-NIC.ARPA with TCP; Mon 28 Sep 87 05:17:24-PDT
Date: Mon 28 Sep 87 05:17:20-PDT
From: Robert Wentworth <[email protected]>
Subject: another KCC bug?
To: [email protected]
Message-ID: <[email protected]>


A C program I'm compiling using KCC is doing weird things (cf. a previous
bug sent to Ken Harrenstien, KLH@SRI-NIC).  The latest one is that
a statement involving a simple division, choice selection using a macro,
and casting to int produces different results on two successive lines
where it is assigned to different variables of type int.  I've tried
lots of random fixes, to no avail so far (though I assume I can find some
kludge).  I'll include a truncated version of the program as the next message.
Print statements point out where the bug occurs.  Note that, as Ken pointed
out, our version of KCC isn't up to date.

-- Bob
-------
28-Sep-87 05:22:22-PDT,5172;000000000001
Received: from Sierra.Stanford.EDU by SRI-NIC.ARPA with TCP; Mon 28 Sep 87 05:18:55-PDT
Date: Mon 28 Sep 87 05:18:52-PDT
From: Robert Wentworth <[email protected]>
Subject: program containing previously mentioned bug
To: [email protected]
Message-ID: <[email protected]>

/* Program to integrate rigid rotor pde for pdf(orientation,momentum)
 * Relates to optical properties of CS 
 *				      2
 * Author: R. H. Wentworth
 * Last Revised: September 26, 1987
 */

/****************************************************************************/

#include <math.h>
#include <stdio.h>

#define ZDIM 20
#define THETADIM 20
#define PHIDIM 20

#define SQR(x) (x*x)
#define ISEVEN(i) ((i % 2) == 0)
#define ISODD(i) ((i % 2) == 1)
#define MAX(a,b) ((a > b) ? a : b)
#define HYPOT(a,b) sqrt(SQR(a) + SQR(b))

FILE *outfile,*fopen();
static char filnam[20] = "SCR:ROTO.OUT";	/* name of output file */

static int zmax, thetamax, phimax, printratio;
static int z, theta, phi, printcount;
static double tnthetamax, tnphimax;
static double zstep, thetastep, phistep, xistep, halfxistep, xilimit;
static double gamma, gainmax, ximax, xiprmin, xiprmax, xi;
static double temp1, temp2, temp3, temp4, temp5;
static double gainz, gaintheta, gainphi;
static double sinz[ZDIM], cotz[ZDIM], _sinz[ZDIM-1], _cotz[ZDIM-1];
static double tansqtheta[THETADIM], tansecsqtheta[THETADIM];
static double _tansqtheta[THETADIM-1], _tansecsqtheta[THETADIM-1];
static double tanphi[PHIDIM], secsqphi[PHIDIM];
static double _tanphi[PHIDIM-1], _secsqphi[PHIDIM-1];
static double wscstheta[THETADIM], wscsphi[PHIDIM];
static double _wscstheta[THETADIM-1], _wscsphi[PHIDIM-1];
static double thetaphiint[ZDIM], _thetaphiint[ZDIM-1];
static double wquadrupole[ZDIM], wmonopole[ZDIM];
static double quadrupole, monopole;
static double q[ZDIM][THETADIM][PHIDIM], _q[ZDIM-1][THETADIM-1][PHIDIM-1];
static double equilib[THETADIM][PHIDIM], _equilib[THETADIM-1][PHIDIM-1];
static double vsinz[ZDIM], vcotz[ZDIM], vsecsqphi[PHIDIM];
static double _vsinz[ZDIM-1], _vcotz[ZDIM-1], _vsecsqphi[PHIDIM-1];
static double vequilib[THETADIM][PHIDIM], _vequilib[THETADIM-1][PHIDIM-1];
static double vinit, _vinit;
static double q000, q001, q010, q011, q100, q101, q110, q111;

/****************************************************************************/

main()
{
int inttrash; /* debug only! */

    /* define integration parameters */

    zmax = 10;		/* number of points in z, minus 1 */
    thetamax = 10;	/* number of points in theta, minus 1 */
    phimax = 10;	/* number of points in phi, minus 1 */
    tnthetamax = 3.0;	/* maximum tan(theta) used (not quite boundary) */
    tnphimax = 3.0;	/* maximum tan(phi) used */
    gamma = 0.0;	/* damping rate */
    gainmax = 0.8;	/* maximum numerical gain (<1 for stability) */
    ximax = 6.0;	/* maximum normalized time */
    xiprmax = 0.1;	/* take time steps at least this small */
    xiprmin = 0.02;	/* don't bother printing steps smaller than this */

/* temporary hack */
/*printf("enter gamma: ");
scanf("%g",&gamma);
printf("enter zmax: ");
scanf("%d",&zmax);
thetamax = zmax;
phimax = zmax;
printf("enter gainmax: ");
scanf("%g",&gainmax);*/

    /* check validity */

    if (ISODD(zmax) || zmax>=ZDIM)
        printf("# illegal zmax: %d\n",zmax);
    if (ISODD(thetamax) || thetamax>=THETADIM)
        printf("# illegal thetamax: %d\n",thetamax);
    if (ISODD(phimax) || phimax>=PHIDIM)
        printf("# illegal phimax: %d\n",phimax);

    /* calculate derived integration parameters */

    zstep = 2.0/zmax;
    thetastep = 2*atan(tnthetamax)/(thetamax-1);
    phistep = 2*atan(tnphimax)/(phimax-1);
    temp1 = zstep*(0.5*zmax - 0.5);	/* near-singular z */
    temp2 = thetastep*(0.5*thetamax - 0.5);	/* theta */
    temp3 = phistep*(0.5*phimax - 0.5);		/* phi */
    gainz = tan(temp3)*sqrt(1 - SQR(temp1))/zstep;
    gaintheta = sqrt((1.0/SQR(temp1)) - 1.0) * tan(temp2) * tan(temp3) /
        (SQR(cos(temp2)) * thetastep);
    gainphi = sqrt((1.0/SQR(temp1)) - 1.0) *
	SQR(tan(temp2) / cos(temp3)) / phistep;
    halfxistep = gainmax / MAX(MAX(gainz,gaintheta),MAX(gainz,gainphi));
    if (2*halfxistep > xiprmax) halfxistep = xiprmax;
    xistep = 2 * halfxistep;			/* time increment */
    gainz = gainz * halfxistep;		/* gains (for diagnostics) */
    gaintheta = gaintheta * halfxistep;
    gainphi = gainphi * halfxistep;
printf("WEIRDNESS HAPPENS HERE!\n");
printf("%g %g %g %g", xiprmin, xistep, xiprmin/xistep, MAX(1.0,(xiprmin/xistep)));
    inttrash = MAX(1.0, (xiprmin/xistep));
    printratio = MAX(1.0, (xiprmin/xistep));
printf(" %d = %d ???\n",inttrash,printratio);
    xilimit = 1.5*xistep + xistep*printratio * ceil(ximax / (xistep*printratio));

    /* output parameter information */

    printf("Print ratio=%d, Total printed points=%d\n",
        printratio, (int)(1+ ximax / (xistep*printratio)));
    printf("Z-gain=%g, Theta-gain=%g, Phi-gain=%g\n", gainz,gaintheta,gainphi);
    printf("xi-increment=%g, damping-factor=%g\n", xistep,gamma);

}
-------
28-Sep-87 20:37:53-PDT,1829;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 28 Sep 87 20:35:22-PDT
Date: Mon, 28 Sep 1987  21:33 MDT
Message-ID: <[email protected]>
From: [email protected]
To:   [email protected]
cc:   [email protected], [email protected]
Subject: More on ECHO and RAW modes

While waiting for a fix to _csetp(), I've been patching the
executables I've been generating to bypass the -1 tests on the tty
speeds.  The programs now work for all cases, except downloads (to the
pc) of binary files through a TAC (with network binary turned on using
local EXEC commands).

The program turns on RAW and turns off ECHO.  It *should* have worked,
except, after considerable debugging, I discovered why it didn't: if
the data stream contains a pair of IAC (FFH) characters, only one is
sent.  Another program sends both such characters with the same data
stream.  In our environment, the monitor doubles the IAC characters
for the user.  In other TOPS20 systems, the user program must do the
doubling.

So, for reference and possible inclusion into the runtime (somehow),
please see PD:<MISC.TOPS-20>TMODEM.MAC on this system.  Take a look at
the code near the beginning at label TMODEM: to use to determine if
the user is on a TAC connection.  The code at NETBON: may be used in
conjunction with a RAW mode request, and at NETBOF: to restore normal
mode.  And, finally, the code at SNDSTR: for an example of how to send
a binary string, possibly containing an IAC, out to a TAC user.

Unfortunately, the code is conditionalized for a compile-time
determination of environment (whether or not IACs are handled by the
monitor).  I do not know of a way to determine this at runtime except
through a user-settable/patchable flag (something in sitdep.h, perhaps?).

--Frank
29-Sep-87 14:33:27-PDT,1373;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Tue 29 Sep 87 14:28:35-PDT
Date: Tue, 29 Sep 1987  17:10 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
Subject: ZT bug status
To:   [email protected]
cc:   [email protected]

Mark,

I finally found the bug in ZT that was showing up as PDL overflows.
It was actually a several level error cascade, but the root cause
is buggy WKS handling code in RPKT.C, which ends up trashing the free
list, which causes malloc() to try to write a bug message to stderr,
which causes fprintf() to try to allocate some freespace to use as a
buffer, which triggers the malloc() error message again, and around
we go....  The WKS parsing error is no real surprise, and I should
have that fixed sometime Real Soon Now.

I'm cc'ing this message to BUG-KCC because this is not the first time
I've seen this kind of problem.  In particular, the routines in
MALLOC.C should not require the freelist to be intact in order to be
able to report errors.  I realize that there are some compatability
issues here, but the current behavior is obscure and fairly painful to
track down.  Given that MALLOC.C already has CPU and opsys dependent
code, it doesn't seem like it would be too horrible to handle this
with a tiny assembly language routine.

--Rob
30-Sep-87 00:22:23-PDT,3872;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Wed 30 Sep 87 00:17:41-PDT
Date: Wed, 30 Sep 1987  03:18 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
cc:   [email protected], [email protected]
Subject: It finally got it all together then forgot where it put it

It looks like the correct calculation is being done but the compiler
loses track of how many pointers it had to follow in the process.

[PHOTO:  Recording initiated  Wed 30-Sep-87 2:32AM]

 MIT TOPS-20 Command Processor 5(312160)-2
XX>foo 241000066241 341000066244
p1=241000066241, p2=341000066244, pp2=&p2, (*pp2)=341000066244
p2-p1=13, (*pp2)-p1=141
XX>pop

[PHOTO:  Recording terminated  Wed 30-Sep-87 2:33AM]

Here's the C code:

#include <stdio.h>

char *p1, *p2, **pp2 = &p2;

main(argc,argv)
    int argc;
    char **argv;
{
    sscanf(argv[1],"%o",&p1);
    sscanf(argv[2],"%o",&p2);
    printf("p1=%o, p2=%o, pp2=&p2, (*pp2)=%o\n",p1,p2,(*pp2));
    printf("p2-p1=%o, (*pp2)-p1=%o\n",diff1(),diff2());
}

diff1()
{
    return(p2 - p1);
}
diff2()
{
    return((*pp2) - p1);
}

And here's the MACRO code:

	TITLE	foo
	.REQUEST C:LIBc.REL
	$$CVER==<2,,1>
	INTERN $$CVER
	OPDEF ADJBP [IBP]
DEFINE %CHRBP(A,M)
<	SETO A,
	ADJBP A,M
>
IFNDEF ERJMP,< OPDEF ERJMP [JUMP 16,] >
OPDEF ERJMPA [ERJMP]
OPDEF	XMOVEI	[SETMI]
	DEFINE IFIW <SETZ >
	TWOSEG	400000	
	RELOC	0	
	RELOC	400000	
	DEFINE %%CODE <RELOC>
	DEFINE %%DATA <RELOC>
PURGE IFE,IFN,IFG,IFGE,IFL,IFLE,IFDEF,IFNDEF,IFIDN,IFDIF

	%%DATA
p1:	BLOCK	1
p2:	BLOCK	1
pp2:	$$SECT,,p2

	%%CODE
main:
	XMOVEI 3,p1
	PUSH 17,3
	PUSH 17,[$$BP90+$$SECT,,$1]
	MOVE 4,-4(17)
	PUSH 17,1(4)
	PUSHJ 17,sscanf
	XMOVEI 3,p2
	MOVEM 3,-2(17)
	ADJSP 17,-2
	PUSH 17,[$$BP90+$$SECT,,$2]
	MOVE 4,-4(17)
	PUSH 17,2(4)
	PUSHJ 17,sscanf
	ADJSP 17,-3
	MOVE 4,pp2
	PUSH 17,0(4)
	PUSH 17,p2
	PUSH 17,p1
	PUSH 17,[$$BP90+$$SECT,,$3]
	PUSHJ 17,printf
	ADJSP 17,-4
	PUSHJ 17,diff2
	PUSH 17,1
	PUSHJ 17,diff1
	PUSH 17,1
	PUSH 17,[$$BP90+$$SECT,,$4]
	PUSHJ 17,printf
	ADJSP 17,-3
	POPJ 17,
$4==.
	BYTE	(9) 160,62,55,160
	BYTE	(9) 61,75,45,157
	BYTE	(9) 54,40,50,52
	BYTE	(9) 160,160,62,51
	BYTE	(9) 55,160,61,75
	BYTE	(9) 45,157,12,0
	

$3==.
	BYTE	(9) 160,61,75,45
	BYTE	(9) 157,54,40,160
	BYTE	(9) 62,75,45,157
	BYTE	(9) 54,40,160,160
	BYTE	(9) 62,75,46,160
	BYTE	(9) 62,54,40,50
	BYTE	(9) 52,160,160,62
	BYTE	(9) 51,75,45,157
	BYTE	(9) 12,0
	

$2==.
	BYTE	(9) 45,157,0
	

$1==.
	BYTE	(9) 45,157,0
	

diff1:
	MOVE 6,p2
	LDB 16,[$$BPSZ,,6]
	SUB 6,p1
	MUL 6,$BPMUL(16)
	ASH 7,-$$BSHF
	ADD 6,$BPADT(16)
	ADD 7,(6)
	MOVE 1,7
	POPJ 17,
diff2:
	MOVE 1,pp2
	MOVE 3,0(1)
	LDB 16,[$$BPSZ,,3]
	SUB 3,p1
	MUL 3,$BPMUL(16)
	ASH 4,-$$BSHF
	ADD 3,$BPADT(16)
	ADD 4,(3)
	POPJ 17,

$$CPKI==0
	INTERN $$CPKI
$$CPKA==0
	INTERN $$CPKA

	LIT
$$STRT: JRST $START
	JRST $START+1
	EXTERN	$BPADT
	EXTERN	$BPMUL
	EXTERN	$START
	EXTERN	$$BSHF
	EXTERN	$$BPSZ
	EXTERN	$$BP90
	EXTERN	$$SECT
	EXTERN	$$$CPU
	EXTERN	$$$CRT
;	EXTERN	.sios
;	EXTERN	.FILE.
;	EXTERN	fclose
;	EXTERN	fflush
;	EXTERN	fgetc
;	EXTERN	fprint
;	EXTERN	fputc
;	EXTERN	fputs
;	EXTERN	fread
;	EXTERN	fscanf
;	EXTERN	fseek
;	EXTERN	fwrite
	EXTERN	printf
;	EXTERN	puts
;	EXTERN	scanf
;	EXTERN	sprint
	EXTERN	sscanf
;	EXTERN	ungetc
;	EXTERN	ftell
;	EXTERN	fgets
;	EXTERN	gets
;	EXTERN	fopen
;	EXTERN	fdopen
;	EXTERN	freope
;	EXTERN	sopen
;	EXTERN	.clean
;	EXTERN	rewind
;	EXTERN	setbuf
;	EXTERN	.setbu
;	EXTERN	setlin
;	EXTERN	.filbu
;	EXTERN	.reada
;	EXTERN	.write
;	EXTERN	.prime
;	EXTERN	.siofl
;	EXTERN	.makeF
;	EXTERN	.freeF
;	EXTERN	.setFI
	INTERN	p1
	INTERN	p2
	INTERN	pp2
	INTERN	main
	INTERN	diff1
	INTERN	diff2
	END <2,,$$STRT>
 1-Oct-87 15:14:08-PDT,556;000000000001
Mail-From: KLH created at  1-Oct-87 15:09:58
Date: Thu, 1 Oct 87 15:08:31 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: It finally got it all together then forgot where it put it
To: [email protected], [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

What version of KCC were you using?  It compiles fine for me (that is, the
diff2 routine includes a MOVE 1,4 to put the result in the right place).
-------
 1-Oct-87 16:28:01-PDT,968;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Thu 1 Oct 87 16:26:10-PDT
Date: Thu, 1 Oct 1987  19:02 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   Ken Harrenstien <[email protected]>
Cc:   [email protected], [email protected]
Subject: It finally got it all together then forgot where it put it
In-reply-to: Msg of 1 Oct 1987  18:08-EDT from Ken Harrenstien <[email protected]>

    Date: Thursday, 1 October 1987  18:08-EDT
    From: Ken Harrenstien <[email protected]>

    What version of KCC were you using?  It compiles fine for me (that is, the
    diff2 routine includes a MOVE 1,4 to put the result in the right place).

The compiler sources are vanilla copies of NIC:SS:<KCC-3.KCC>.
Everything has been recompiled locally.

If/when there's a newer source release I'll be happy to install it.
I'm reluctant to try supporting the resolver without compiler sources.
 1-Oct-87 16:38:03-PDT,483;000000000001
Mail-From: KLH created at  1-Oct-87 16:36:54
Date: Thu, 1 Oct 87 16:36:40 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: It finally got it all together then forgot where it put it
To: [email protected]
cc: [email protected], [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

OK, fine.  I'm going to give it one more week and then put KCC-4
together.
-------
 2-Oct-87 15:24:19-PDT,688;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Fri 2 Oct 87 15:19:25-PDT
Date: Fri, 2 Oct 1987  16:20 MDT
Message-ID: <[email protected]>
From: [email protected]
To:   [email protected]
cc:   [email protected]
Subject: LINK problem w/LIBC.REL.204?

I have a program with the following relevant lines:

time_t	timep[2];

	timep[0] = time(NULL);

No complaints until the LINK step:

%LNKFTH	Fullword value TIME being truncated to halfword
%LNKMDS	Multiply-defined global symbol TIME
	Detected in module TIME from file <KCC-4.INCLUDE>LIBC.REL.204
	Defined value = 104000000014, this value = 434111

What should I check?

--Frank
 2-Oct-87 15:44:14-PDT,560;000000000001
Mail-From: KLH created at  2-Oct-87 15:42:23
Date: Fri, 2 Oct 87 15:42:17 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: LINK problem w/LIBC.REL.204?
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Do you have assembler code in that program somewhere?  The linker is
complaining because you are making use of the TIME% jsys (JSYS 14) and
that definition obviously conflicts with the time() function symbol.
-------
 2-Oct-87 16:29:19-PDT,802;000000000001
Received: from SCIENCE.UTAH.EDU by SRI-NIC.ARPA with TCP; Fri 2 Oct 87 16:28:19-PDT
Date: Fri 2 Oct 87 17:29:40-MDT
From: "Nelson H.F. Beebe" <[email protected]>
Subject: Re: LINK problem w/LIBC.REL.204?
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
X-US-Mail: "Center for Scientific Computation, South Physics, University of Utah, Salt Lake City, UT 84112"
X-Telephone: (801) 581-5254
Message-ID: <[email protected]>

You are getting a conflict with the TIME% JSYS (# 14) and
the external symbol TIME for the C function of the same
name.  I hit a similar problem in putting up the new awk on
the -20; it had external functions named ARRAY, which caused
MACRO to belch.
-------
 2-Oct-87 17:54:15-PDT,1218;000000000001
Mail-From: KLH created at  2-Oct-87 17:53:50
Date: Fri, 2 Oct 87 17:53:48 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: More on ECHO and RAW modes
To: [email protected], [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

I'm not sure what you want.  Are you saying that for some kinds of file
descriptors, the unix simulation routines should check for IAC bytes?
Is this what 4.3 (or any other) UNIX does?  What we want to do is
whatever most Unix systems do.

As for the TTY speed problem, the problem is that Unix seems to have no way
of indicating that a speed is "unknown".  This could possibly be 0, which
however is used to mean "hangup".  4.3 appears to set the speed of network
ptys to 017, which would be EXTB in DH-11 lingo but is interpreted as 38400
baud by the "stty" program.

Note that -1 is not a valid constant value for the speed values in the sgttyb
structure, since they are declared as "char"s which for KCC are unsigned;
attempting to set them to -1 will result in the value 511 (0777).

I'm still thinking about the best solution...
-------
 3-Oct-87 09:34:29-PDT,1883;000000000001
Received: from SUMEX-AIM.STANFORD.EDU by SRI-NIC.ARPA with TCP; Sat 3 Oct 87 09:25:44-PDT
Received: from PANDA.COM by SUMEX-AIM.STANFORD.EDU with Cafard; Sat, 3 Oct 87 09:24:48 PDT
Date: Sat, 3 Oct 87 09:21:56 PDT
From: Mark Crispin <[email protected]>
Subject: Re: More on ECHO and RAW modes
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Postal-Address: 1802 Hackett Ave.; Mountain View, CA  94043-4431
Phone: +1 (415) 968-1052
Message-ID: <[email protected]>

Ken -

     Here are some facts that may help put things into perspective.

1) All TOPS-20's report the speed of a software terminal as being -1.  This
   means indeterminate.  The KCC routines must be able to handle this situation
   with something reasonable.  You cannot set the speed of a software terminal.
   I think the best thing to do is to ERJMP .+1 in these cases, and kludge up
   some reasonable fake value.

2) All TOPS-20's, with the exception of PANDA TOPS-20's, fail to double IAC's.
   Certain programs have taken advantage of this bug to deliberately send Telnet
   protocol outside of TTANDV/TVTSRV.  This can't be done on PANDA TOPS-20's.
   As far as I can see, the only thing you want to do is negotiate binary mode;
   PANDA TOPS-20's have an MTOPR% to do this.

3) PANDA TOPS-20's had a bug that caused them to fail to double IAC's if they
   were given a SOUT% with a negative count.  This was caused by the cutesy
   BLAST routine from Stanford.  Since BLAST cannot possibly work for TVT's if
   you have IAC doubling and correct TVT newline handling, I patched it out at
   SIMTEL20 and edited the source so BLAST is instructed to decline to do its
   thing for a TVT.

     The bug noted in (3) confused Frank and may have made his messages to you
unclear.

-- Mark --
-------
 3-Oct-87 15:59:32-PDT,2273;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sat 3 Oct 87 15:54:57-PDT
Date: Sat, 3 Oct 87 16:54:23 MDT
From: Frank J. Wancho <[email protected]>
Subject: Re: More on ECHO and RAW modes
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

First, it is *easy* to determine at runtime if the user is on a net
connection.  You could set a flag for later use.  The hard part is
determining whether the IACs need to be doubled.  I believe that the
ISI monitors also double IACs as well as the PANDA monitors.  The
difference is that the PANDA monitors provide a way for the user
program to cause network binary mode to be negotiated via an MTOPR%
call.

However, checking for failure on that MTOPR% call is not conclusive
either.  The bits Mark chose are used by other monitors for other
purposes.  It's unfortunate that the bits used were not standardized
and that all monitors double IACs on net tty output.

So, let's make part of this "easy".  Assume the default case is that
the monitor does not double IACs.  This means that part of write()
will have to be special-cased to terminal output: if the terminal is
not a net connection as determined above, or in RAW mode, use the
present output routines.  Otherwise, if it is a net connection AND RAW
mode has been requested, double IACs on output and negotiate net
binary mode.  See TMODEM.MAC at label SNDSTR: for an example of one
way it can be done with SOUTR%, which avoids the overhead of checking
each character.  See TMODEM.MAC at labels NETBON: and NETBOF: for
example on how to do net binary negotiations.

Now, for the exception handling: let there be a new IOCTL flag, which
is handled like RAW, except that it means, do not do net binary
negotiations and do not double IACs.  In other words, handle the
output as is done now, except for the speed check.  (Have the speed
return 9600 for net connections as most Unix systems seem to return
that fixed value.)  In our case, I will provide the PANDA equivalent
MTOPR% calls to then negotiate network binary mode because that is not
universal.

Did I oversimplify the solutions?

--Frank
-------
 3-Oct-87 21:54:38-PDT,740;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sat 3 Oct 87 21:44:50-PDT
Date: Sat, 3 Oct 1987  22:46 MDT
Message-ID: <[email protected]>
From: [email protected]
To:   [email protected]
cc:   [email protected]
Subject: TIME and time() conflict

All who responded correctly analyzed my problem - I have some assembly
code with a SEARCH MONSYM in it, which causes the name conflict.  It's
unfortunate that MONSYM has to handle both old and new formats or this
wouldn't be a problem.

Thanks for the prompt responses.  I presume the fix is to translate
these routines into their C equivalents using jsys(), which I really
wasn't planning to do, but it seems I have no choice...

--Frank
 3-Oct-87 22:09:37-PDT,474;000000000001
Mail-From: KLH created at  3-Oct-87 22:05:46
Date: Sat, 3 Oct 87 22:05:41 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: TIME and time() conflict
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

You could try putting a PURGE TIME immediately after the SEARCH MONSYM
in whichever file is referencing it, and use just TIME%.
-------
 3-Oct-87 22:14:38-PDT,547;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sat 3 Oct 87 22:08:26-PDT
Date: Sat, 3 Oct 87 23:10:17 MDT
From: Frank J. Wancho <[email protected]>
Subject: Re: TIME and time() conflict
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Ken,
     The assembler code doesn't use TIME% (or TIME).  Only the
subsequent C code in the same module references it.  Would PURGE TIME
still be OK?

--Frank
-------
 3-Oct-87 22:29:41-PDT,613;000000000001
Mail-From: KLH created at  3-Oct-87 22:29:37
Date: Sat, 3 Oct 87 22:29:33 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: TIME and time() conflict
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

C code cannot reference any symbols from MONSYM.UNV (or MONSYM.FUN).  I
don't understand how you are generating the reference to the TIME jsys
if it isn't used by assembler code.  And if it isn't referenced it shouldn't
be in the .REL's symbol table.  So I'm puzzled.
-------
 4-Oct-87 08:19:44-PDT,680;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sun 4 Oct 87 08:14:21-PDT
Date: Sun, 4 Oct 87 09:16:18 MDT
From: Frank J. Wancho <[email protected]>
Subject: Re: TIME and time() conflict
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Ken,
    This program is a port of yet another file transfer program pair.
The author used a #include mumble.c, and mumble.c contains code common
to both and the assembler code.  I was making only minimal changes to
make it work, not an overhaul.  Thus, the conflict in the symbols.

--Frank
-------
 4-Oct-87 13:09:50-PDT,1386;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Sun 4 Oct 87 13:04:43-PDT
Date: Sun 4 Oct 87 16:07:46-EDT
From: Rob Austein <[email protected]>
Subject: A question and a suggestion
To: [email protected]
Message-ID: <[email protected]>

The question: Is PSI normally turned on in the latest and greatest
KCC?  Do you have plans to have it so in the near future?  My resolver
code seems to be capable of the damnedest errors, including MPVs
caused by bad pointers.  I want to make my bug handling code include
an interrupt handler for panic chanels which will force entry into my
bughlt() code, so that I get crash dumps and other useful stuff.
Obviously, which way I do this depends on how much use KCC makes of
the interrupt stuff, and whether or not I can ignore KCC's use of it
if I'm not using sigvec().

The suggestion: It would be nice if the reentry address for KCC
programs eventually ended in a call to abort() or some such thing so
that those of us who supply our own abort() routine will win.  As it
is, making a crash dump of a resolver that has lost due to MPV errors
as above is painful, particularly since by the time a program is in
bad enough shape to need a crash dump the symbol table is trash.  If
the PDL hasn't been initialized, the current behavior would be ok, I'm
not asking for miracles.

Thanks.
-------
 4-Oct-87 13:45:08-PDT,1159;000000000001
Mail-From: KLH created at  4-Oct-87 13:41:40
Date: Sun, 4 Oct 87 13:41:38 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: A question and a suggestion
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Unless you make an explicit call to sigvec() or signal(), the PSI system
is never turned on; this is to reduce overhead.  If turned on, only those
channels which the user references are activated.  So, to handle all
panic channels with your own bughlt() routine, you'll need to specify that
handler for all of the signals that include those channels.  SIGNAL.DOC
explains this in more detail.

There is one problem with this: if the panic PSI happens in USYS code,
your handler may not be invoked (depends on whether the interrupt was
due to a JSYS or not, etc).

You can use the PSI system all by yourself if you never reference the signal
routines; there will be no conflict.  This is a bit painful, though.

I'm not sure I understand your suggestion.  What does re-entry have to
do with crash dumps?
-------
 4-Oct-87 14:14:49-PDT,363;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sun 4 Oct 87 14:11:08-PDT
Date: Sun, 4 Oct 1987  15:12 MDT
Message-ID: <[email protected]>
From: [email protected]
To:   [email protected]
cc:   [email protected]
Subject: mktemp() bug

mktemp() returns a pointer to a new string rather than to the template.

--Frank
 4-Oct-87 14:54:49-PDT,2115;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Sun 4 Oct 87 14:49:07-PDT
Date: Sun, 4 Oct 1987  17:52 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   Ken Harrenstien <[email protected]>
Cc:   [email protected]
Subject: A question and a suggestion

REENTER is the normal command for putting a program into a known state
when it has exited for unknown reasons.  Some programs take it as
meaning clean up and exit.  In my particular case I'd make REENTER
cause a crash dump because the entry vector is one of the few things
that I can count on (probably) still being intact, but that's a
BUG-CHIVES issue, not a BUG-KCC issue.

My point is that KCC does absolutely nothing useful with this entry
vector position, and that it would be trivial to make it do something
useful.  Perhaps it could call a routine $REENT; if the user supplies
such a routine, fine, otherwise $REENT is a LIBC routine that does
some "reasonable" cleanup action, perhaps just uses the normal exit()
code.

The current code takes a lot of pains to make sure that the program
will bomb if the user ever restarts or REENTERs it.  This is
reminicent of the patch DEC sent for EDT-20, which, when you try to
restart it, tells you that VMS doesn't have a REENTER command so you
should get yourself out of the habit of using it even on TOPS-20.

The only case where the current behavior is justified is when you
think the stack pointer is invalid; that should be trivial to check.

The one other thing that would be needed to support this properly
would be a fixup of the entry vector by the same code that SMAP%s
extended programs into section one.  Not a big deal.

While we're down in the CRT/URT level stuff, I'm curious why
redirection of stderr isn't supported.  Is it because of the
differences in syntax between the different unix shells?  Or because
nobody has ever bothered to write the code?  Or some other reason?
The first case should be solvable, the second case I'd be interested
in amending, the third case I'd like to hear about.
 4-Oct-87 17:09:54-PDT,1971;000000000001
Mail-From: IAN created at  4-Oct-87 17:09:06
Date: Sun, 4 Oct 87 17:09:00 PDT
From: Ian Macky <[email protected]>
Subject: Re: mktemp() bug
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

You are right, mktemp() was not doing the correct thing.  Here's a fix,
plus a bonus enhancement...


;COMPARISON OF SS:<C.LIB.STDIO>MKTEMP.C.1 AND SS:<C.LIB.STDIO>MKTEMP.C.8
;OPTIONS ARE    /3

**** FILE SS:<C.LIB.STDIO>MKTEMP.C.1, 1-16 (466)
char *mktemp(pattern)
char *pattern;
{
    char *s, *malloc();
    int pid, i;
    int ablock[5];
    s = malloc(strlen(pattern)+1);	/* copy string */
    if (s == 0) return "???";		/* no memory left, lose */
    strcpy(s, pattern);			/* into a new place */
    pattern = s;			/* forget about the old one */
**** FILE SS:<C.LIB.STDIO>MKTEMP.C.8, 1-16 (466)
char *mktemp(buf)
char *buf;
{
    char *s = buf;
    int pid, i;
    int ablock[5];
***************

**** FILE SS:<C.LIB.STDIO>MKTEMP.C.1, 1-47 (1331)
    s++;				/* look at top digit */
    i = 'a';				/* start at top of alphabet for fix */
    while (access(pattern, 0) != -1) {	/* until we find a good file */
        if (i == 'z') return "???";	/* out of files, force err in caller */
	*s = i++;			/* otherwise try new char */
    }
    return pattern;			/* got good file, return the name */
**** FILE SS:<C.LIB.STDIO>MKTEMP.C.8, 1-41 (1100)
    if (access(buf, 0) == -1)		/* file exist? */
	return buf;			/* nope, so we won! */
    while (*++s) {
	for (i = 'a'; i <= 'z'; i++) {	/* loop from 'a' to 'z' */
	    *s = i;			/* try replacing old with letter */
	    if (access(buf, 0) == -1)	/* look again.  file there? */
		return buf;		/* no, so won, return buf ptr */
	}				/* else loop and try next letter */
    }					/* all in use, try next position */
    return 0;				/* lost our ass!! */
***************
-------
 5-Oct-87 03:34:58-PDT,3373;000000000001
Mail-From: KLH created at  5-Oct-87 03:31:08
Date: Mon, 5 Oct 87 03:31:04 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: A question and a suggestion
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Well, I've been using T20 for several years now, and I can't remember
ever using REENTER.  Not once.  What was I missing?  Anyway, I have no
idea what behavior it should elicit from a program.  Evidently it was
more useful on T10.  And the concept has no meaning on ITS.

I can't think of any easy way to restart a C program.  The problem is that
you have all of these variables that are no longer initialized to what
they should be, zero or otherwise.  C programs normally do not do
any explicit initialization, so restarting leaves EVERYTHING messed up: the
storage allocation, the stdio data, the USYS data, etc; if the process was
SSAVEd and then restarted there are even worse inconsistencies like PID
value, local timezone, and so on.  All of these would have to be tracked
down and reset by a general "re-start" capability.  Is it worth it?

I am not sure what you want REENTER to do, really, that cannot be done
in other ways.  Allowing the user to provide a $REENT label would be
possible but what do you want it to do?  Jump directly there?  Call it
like a C function?  What should the default action do?  Take a dump?
Why not just SAVE the fork manually?
	In general you cannot continue program execution elsewhere
after interrupting at an arbitrary place, because the data structures
could be inconsistent; for example, attempting to fclose() a stream
after being interrupted from the middle of fiddling with the stream's
variables could cause problems.  Even the low-level USYS routines have
this problem.  I would feel very uncomfortable trying to describe a
"feature" which could only be safely used in certain unusual
circumstances which the programmer must completely understand.

The best way to halt a C program such that it can be continued
(reentered, if you will) is to do a jsys(HALTF,acs), and then do
whatever is needed if control returns.  You can get back to the main
routine by using longjmp(), although of course the command line input
(argv, argc) will not have changed.  There is no counterpart to this
on UNIX, although it's true that some signals will cause a "core" file
to be dumped.  Is this what you want?  I didn't bother as I reasoned
this misfeature existed only because UNIX did not allow dead forks to
remain hanging around; on T20 one can splice IDDT in, or simply SAVE
a corpse if necessary.

I've considered adding a special function that would do most of the
necessary things to allow a program to be restarted, and then exit so
the initialized image could then be dumped; a primary use for this would be
to set up extended-addressing programs for faster runtime loading, akin
to the PURIFY$G schemes of some programs.  But it always seemed too
painful and I had other things to do.  Would this be relevant?


Stderr redirection: the syntax used on UNIX is very ugly (have you
seen it?), which is the main reason no one has bothered to write the
code.  If you want to do it, you're welcome.  Be careful of the
existing meaning of &.
-------
 5-Oct-87 17:35:26-PDT,1266;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 5 Oct 87 17:32:10-PDT
Date: Mon, 5 Oct 1987  18:33 MDT
Message-ID: <[email protected]>
From: [email protected]
To:   [email protected]
cc:   [email protected]
Subject: utime() and fstat() not symmetrical

To demonstrate, set an arbitrary file's .FBCRE, .FBCRV, and .FBWRT
with three different dates via REV.  Run the following program with
that filename as the argument, and then check the times with REV.  The
result is that whatever is in .FBWRT is written to .FBCRE.

If anything, the greater of .FBWRT and .FBCRV should be considered the
last modification date.  That would normally be .FBWRT and written
back to .FBWRT (and maybe .FBCRV under certain conditions).  In no
case should .FBCRE be changed.

--Frank
--------------------

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
struct stat fbuf;
time_t timep[2];

main(argc, argv)
int argc;
char **argv;
{
	FILE *infile;

	if ((infile = fopen(argv[1], "r")) == NULL) {
		perror (argv[1]);
		continue;
	}
	fstat(fileno(infile), &fbuf);
	fclose(infile);
	timep[0] = fbuf.st_atime;
	timep[1] = fbuf.st_mtime;
	utime(argv[1], timep);
  	}
}
====================
 6-Oct-87 00:25:30-PDT,1444;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Tue 6 Oct 87 00:19:57-PDT
Date: Tue, 6 Oct 1987  01:21 MDT
Message-ID: <[email protected]>
From: [email protected]
To:   [email protected]
cc:   [email protected]
Subject: More on IAC doubling

MRC came up with one possible way to determine if IAC doubling is
required at runtime.  However, the more I think about it, the more I
think a better general solution would be for KCC to auto #include a
<site.h> or some equivalently named file, if it exists, to allow the
setting of certain site-unique variables and #defines, etc.  Then,
based on the value of those variables, the runtimes can determine
various operating modes to use for that site.  Unfortunately, the
resulting executables are then inherently not portable to other TOPS20
machines.  (I'd still like a generic #define of TOPS20 set to TRUE so
I don't have to remember to insert a -DTOPS20 in the cc line...)

So, how to do this?  Well, something else has always bothered me about
KCC produced executables, and that is its size.  Even the smallest
program (main(){}) results in a 31 disk page executable.  If you
consider making all that overhead a loadable KCCOTS.EXE, ala FORTRAN,
with a "make" file on how to generate a site-dependent version, we
would take care of at least two problems.  Given a symbol table with
definitions, it could even be patchable!

--Frank
 6-Oct-87 01:25:31-PDT,2762;000000000001
Mail-From: KLH created at  6-Oct-87 01:23:39
Date: Tue, 6 Oct 87 01:23:36 PDT
From: Ken Harrenstien <[email protected]>
Subject: IACs, RAW mode, TTY speed, etc
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Please send me the method for runtime determination of whether the monitor
does IAC doubling.

I looked at the 4.3BSD sources.  The telnet server appears to always double
IACs, so user programs should never have to know about this.  Consequently,
I'm agreeable to having the KCC runtime check for this and do the doubling.
But if your monitor was already doing this doubling, why are you having
a problem in the first place?

Whether the RAW bit should reflect the state of binary mode is a more
difficult question.  My inclination is to think it should not.
I have not looked at the 4.3 code to see what it does, although I suspect
it does nothing.  There are many programs that use RAW for purposes
unrelated to transferring binary data files, and if one of those programs
dies while you are in binary mode, you are in trouble; the EXEC will not
renegotiate things.  I think this will have to be application specific,
conditionalized for TOPS-20.

The 4.3BSD kernel sets the speed for PTYs to EXTB.  I have changed ioctl() so
that EXTB is returned when the speed is unknown (-1 on T20); also, if the
MTOPR% fails while setting the speed, ioctl() ignores the failure.  It will
still fail prematurely if the user provides an unknown UNIX speed code.

It's unfortunate that (besides failing to double IACs) T20 doesn't permit
the TTY speed variables to be set for software TTYs.  The speed values
are often needed by cursor control routines.  UNIX does permit them to
be set even when there is no hardware effect, and this is quite useful.

If you need to include site dependent definitions, include <c-env.h>.  This
is what that file is for.  Or use a makefile or .MIC with the appropriate
compilation flags.  The problem with auto-inclusion of a file is that this
would not be portable at all (whereas with the other constructs things are
either portable or easily noticed).

The shared library idea is on the list, but it does not have high priority.
If someone were to fix the T20 linker so it permitted the high segment
to start below 400000 then I would be much more interested.  At the moment
I am more concerned with making things work right (and getting my other
work done).

I don't wish to diminish the flow of ideas or suggestions, most of
which are good -- just pointing out the sad fact that we don't have
enough resources to pursue them more actively.  Sigh!
-------
 6-Oct-87 09:35:24-PDT,4505;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Tue 6 Oct 87 09:28:44-PDT
Date: Tue, 6 Oct 1987  10:30 MDT
Message-ID: <[email protected]>
From: [email protected]
To:   Ken Harrenstien <[email protected]>
Cc:   [email protected], [email protected]
Subject: IACs, RAW mode, TTY speed, etc
In-reply-to: Msg of 6 Oct 1987  02:23-MDT from Ken Harrenstien <KLH at SRI-NIC.ARPA>

If it has been separately determined that the user is on a TAC
connection (that MACRO code is appended below), and RAW mode has been
requested, send IAC WONT ECHO.  If IACs are doubled by the monitor,
the side effect will be that the user will see a rubout, tilde, and ^A
with the high bits set.  If IACs aren't doubled, the TAC will return
IAC DONT ECHO, which will be intercepted by all TOPS20 monitors and
set line halfduplex.  The catch is that it takes some finite amount of
time for this action to occur (maybe about four seconds) before that
state of the duplex mode can be checked after sending that string.  If
the mode is changed, the output routine must then undo that request to
restore the state of the terminal, and then send the sequence to put
the connection into network binary mode and set a flag that IACs need
to be doubled.

The sequence to turn network binary mode on is: send IAC DO TRNBIN,
wait four seconds, then send IAC WILL TRNBIN, and wait another four
seconds.  The four second wait is an empirically determined wait,
known to work, and required because these negotiations occur
asynchronously (separately from the normal output stream).  Without
the waits, it is possible for binary output to be sent or received in
non-binary mode.

The sequence to turn network binary mode off is: send IAC WONT TRNBIN,
wait four seconds, then send IAC DONT TRNBIN.

The reason I was having trouble with IAC doubling is that of the three
possible modes to use SOUT%, two out of the three resulted in doubled
IACs.  The third, a negative string length in C, used by write(), did
not result in doubled IACs.  TMODEM uses a positive count with a 377
in D, and a check to see if C is 0.  If C is not 0, then the SOUT% was
repeated in a loop.  This worked for both cases where the IACs are
doubled or not.  When they are not doubled by the monitor, the case of
the non-zero C meant that a single IAC needed to be sent before the
loop continued.  Furthermore, if IACs aren't doubled, the last
character in the just sent string needs to be checked in the
successful SOUT% to see if it was an IAC, and send another if it was.

There is no big deal about a program aborting while in network binary
mode, even though the EXEC does not go to the same trouble to restore
"sane" tty characteristics as some Unix shells do.  About all I've
seen is that page mode remains disabled, which is a required RAW mode
setup in a TOPS20 environment.  Unlike the meaning of RAW mode in
Unix, it is perfectly useable to be in network binary mode during all
aspects of a TOPS20 session.

BTW, RAW mode should also save the state of links and system messages,
and optionally turn them off if NOECHO is also requested.  Links and
system messages can disrupt file transfers, if that is the reason for
the RAW request.  However, there may be cases where RAW is requested
for some other purpose in a conversational mode.  If the state is RAW
and ECHO, then it might be a good idea to save the CCOC words and set
them to:

	 dmove	B,[BYTE(2) 1,1,1,1,1,1,1,2,2,3,2,1,1,2,1,1,1,1
	 	   BYTE(2) 1,1,1,1,1,1,1,1,1,1] ; set new COC 
	 SFCOC%			; to echo CR, LF, BS, and TAB properly

--Frank
--------------------

extern	int tacusr;

int
chktac()
{
#asm
	SEARCH	MACSYM,MONSYM

A=:1				; JSYS, temporary AC's
B=:2
C=:3
D=:4

	GJINF%			; Get job info
	MOVE	A,D		; Get terminal number into A
	TXO	A,TCP%TV	; Argument is a TVT
	HRROI	B,7		; Want host number (should have a symbol!)
	HRROI	C,HSTNUM
	STAT%			; Get it
	 ERJMP	[SETZ	A,	; Must not be a TVT
		 RET]
; Stop here and return -1 in A if ALL TELNET connections are acceptable.
; Otherwise, continue if ONLY TAC connections must pass the test.
	MOVX	A,.GTHHN	; Get status of host
	MOVE	C,HSTNUM	;  given host number
	GTHST%
	IFJER.
	 SETZ	D,		; If failed, just clear D
	ENDIF.
	SETZ	A,
	ANDI	D,HS%STY	; Get system type
	CAIE	D,.HSTIP	; Is it a TIP?
	 CAIN	D,.HSTAC	; Is it a TAC?
	  SETO	A,		; It is
	RET

HSTNUM:	BLOCK	1

#endasm
}
====================
 6-Oct-87 16:58:23-PDT,750;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Tue 6 Oct 87 16:53:03-PDT
Date: Tue, 6 Oct 1987  17:53 MDT
Message-ID: <[email protected]>
From: [email protected]
To:   [email protected]
cc:   [email protected]
Subject: Correction on fstat() and utime() bug

fstat() followed by utime() as in the previous demo code copies .FBCRE
to .FBWRT (not the other way around as I had stated).  I still stand
by my algorithm that only the greater of .FBCRV or .FBWRT should be
considered the last modification time.  (.FBCRE should never be
considered as it is not set by the user - the system sets it during a
DUMPER RESTORE operation, for example, and that date is not of
interest to the user.)

--Frank
10-Oct-87 11:49:52-PDT,543;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sat 10 Oct 87 11:48:09-PDT
Date: Sat, 10 Oct 1987  12:49 MDT
Message-ID: <[email protected]>
From: [email protected]
To:   [email protected]
cc:   [email protected]
Subject: "-q" for .EXE files

Some option, if an option is needed at all, should exist such that the
LINK step is executed only if any of the named .REL files or the
library file(s) (i.e., C:LIBC.REL) are newer than the named .EXE file,
or the .EXE file does not exist.

--Frank
11-Oct-87 21:20:12-PDT,1616;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sun 11 Oct 87 21:14:54-PDT
Date: Sun, 11 Oct 1987  22:16 MDT
Message-ID: <[email protected]>
From: [email protected]
To:   [email protected]
cc:   [email protected]
Subject: *dir routines

If you happen to be interested, I have implemented opendir, readdir,
and closedir after a fashion - the fashion is that it is currently set
up to handle only one directory, but can be generalized.  telldir,
seekdir, and rewinddir can also be "easily" be written to complete the
set, and stat()/fstat() need to be tricked to work with them.

Right now, all it does is build an array of pointers to the malloc'd
filenames on opendir, and readdir pulls the next name out of the list,
returning it in the proper structure format.  closedir should release
the space, but I don't know exactly how to do that, nor do I know how
to keep more than one set of arrary pointers around and select the
appropriate one.

One way might be to actually write out a temporary pseudo directory
file on the opendir and have closedir unlink it.  That would make
stat/fstat easy to change and an fd could actually be associated with
the file.  Another way might be to have an in-memory pseudo file.  Is
that latter possible or adviseable?

Anyway, unless you already have something in the works to implement
these routines, I'd like to pass along what I've developed so far
(which is "good enough" for the particular programs I'm working on at
the moment), and you can take it from there any way you want to go
with them.

--Frank
22-Oct-87 18:33:47-PDT,1628;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Thu 22 Oct 87 18:29:12-PDT
Date: Thu, 22 Oct 1987  18:37 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
Subject: backgrounded C programs can't exec() C programs

C progams that are in background (including via a normal invokation
with "&" in the JCL) can't start up C programs (including with the
exec() family of routines); the new invokation will hang trying to
DVCHR% .PRIIN before it ever finishes initializing the URT code.

This could probably be fixed by handling .PRIIN specially, using
SPJFN% to find out if .PRIIN is actually .CTTRM and if so just
returning .DVTTY without doing the DVCHR%.  How gross.

Here's a sample program:

#include <stdio.h>
main(argc,argv)
    int argc;
    char **argv;
{
    int i = atoi(argv[1]) - 1;
    char s[20];
    fprintf(stderr,"%s %s\n",argv[0],argv[1]);
    sprintf(s,"%d",i);
    if(i > 0)
	execl(argv[0],argv[0],s,NULL);
}

and a sample run:

[PHOTO:  Recording initiated  Thu 22-Oct-87 6:27PM]

 MIT TOPS-20 Command Processor 5(312160)-2
XX>kccbug 3
KCCBUG 3
KCCBUG 2
KCCBUG 1
XX>kccbug 3 &
XX>KCCBUG 3
[KCCBUG: wants the TTY]
iddt kccbug

$$./   DVCHR      p/'CRT$:   ANDCAI 7,11347(7)   	
11347/   10000,,.DVTYP+7   ^H
11346/   117   ^H
11345/   11340   ^H
11344/   0   ^H
11343/   0   ^H
11342/   0   ^H
11341/   100   ^H
11340/   0   ^H
11337/   10000,,URT&INIT.U+6   ^H
11336/   100   ^H
11335/   0   

1/   100   
^Z
XX>pop

[PHOTO:  Recording terminated  Thu 22-Oct-87 6:28PM]
26-Oct-87 21:43:14-PST,1303;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 26 Oct 87 21:41:02-PST
Date: Mon, 26 Oct 1987  22:40 MST
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: Burnt again (JSYS.H and MONSYM)

Before the next release, how about changing all the JSYS #defines in
JSYS.H to the jsysname_ format so we can escape the SEARCH MONSYM
conflicts, please?  (Implicit in this are changes to all the jsys()
references in the libaries.)  I think it's time to bite the bullet and
make this one-shot change.

What burned me this time was a hidden reference to GTAD in TIME.C (in
a asm()) which showed up as a multiply defined in the link step
because I happened to have a function named gtad() in my program which
in turn did a jsys(GTAD, ac) call.  I also had a #asm with a SEARCH
MONSYM in it.  The problem was finally solved by renaming my function
to be _gtad(), which I don't understand was really necessary as there
was no entry point conflict with the LIBC modules.  I'm sure you'll
have a good reason for this.  But, I'm getting tired of these
conflicts and I don't want to translate perfectly good and tight MACRO
into C just because of these conflicts.

--Frank
27-Oct-87 08:23:56-PST,1184;000000000001
Mail-From: KLH created at 27-Oct-87 08:23:15
Date: Tue, 27 Oct 87 08:23:09 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Burnt again (JSYS.H and MONSYM)
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Changing the macro name won't solve the problem you encountered with gtad.
I don't entirely understand why the problem exists, but it doesn't have
anything to do with the preprocessor symbols.

If you need to use asm() constructs then just use the lowercase jsys% form
of the symbols.  This will never conflict with any macro name, whether it
is JSYS or JSYS_.  The assembler is case insensitive whereas C is
case sensitive.

Using some standard for those macros is probably a good idea, but it
can't be justified as a solution to the gtad problem and the standard
should ideally cover the other monsym symbols as well.  What I've been
considering is a built-in function such as "monsym(a)" where the arg is
evaluated at compile time as a MONSYM symbol and the constant lookup is
done on the spot from the .UNV file.
-------
29-Oct-87 08:37:02-PST,316;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Thu 29 Oct 87 08:35:20-PST
Date: Thu, 29 Oct 1987  01:04 EST
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
Subject: KCC-4?

Hi, what ever happend to the impending release of KCC-4?
29-Oct-87 16:37:18-PST,906;000000000001
Mail-From: KLH created at 29-Oct-87 16:35:00
Date: Thu, 29 Oct 87 16:34:54 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: KCC-4?
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Well, I was hoping to have it ready by 10/23 but this happens to be
SRI's annual red tape festival, which has delayed things a bit.  If you
want a snapshot you can FTP everything in SS:<KCCDIST*>*.*.  This
directory will turn into <KCC-4> shortly.  In fact I could just copy
it now, but I'm going on a vacation for a few days (back Wed) and
my sense of caution says it would be bad timing.  It is unlikely that
anything will change from <KCCDIST> to <KCC-4>, however, so you can
get that if you want.  Let me know if you do, though, so I can alert you
if changes do happen.
-------
 5-Nov-87 01:02:10-PST,604;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Thu 5 Nov 87 00:57:05-PST
Date: Thu, 5 Nov 1987  00:50 MST
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: Bug in CC.EXE.580

The following generates incorrect code with CC (580) and correct code
with CC (577):

static unsigned short crctab[1] = {0x0000};

#define updcrc(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp)

main()
{
	register unsigned short oldcrc;

	oldcrc = updcrc(0,updcrc(0,oldcrc));
}
 5-Nov-87 13:09:35-PST,677;000000000001
Mail-From: KLH created at  5-Nov-87 13:09:28
Date: Thu, 5 Nov 87 13:09:24 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Bug in CC.EXE.580
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Hmmm.  I changed the preprocessor in an attempt to bring it more in line
with the way ANSI seems to be going; recursive macro usage is one of the
things that are different.  I think your code should work as you intended,
so I'll go over things to make sure that what's happening is really what
should be happening (and fix it if not).
-------
16-Nov-87 22:29:36-PST,920;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 16 Nov 87 22:27:02-PST
Date: Mon, 16 Nov 1987  23:26 MST
Message-ID: <[email protected]>
From: [email protected]
To:   [email protected]
cc:   [email protected]
Subject: Possible scanf bug

The intent of the following line is to skip over the first two strings
and any number of blanks, tabs, right parens, and colons, and copy the
remainder of the line, up to the CR, into buffer.  However, buffer is
empty.  Variations with the trailing %*c and *[ ] instead of *[ \t):]
produce the same results.  Is this a bug or a misunderstanding?

	  num = fscanf(logfile,"%*s%*s%*[ \t):]%[^\n]%*c",buffer);


Sample logfile contents:


15-Nov-87 16:07:25 Daemon wakeup
15-Nov-87 16:07:25  File [--REDIST-MAIL--].RETRANSMIT.6106:
15-Nov-87 16:07:25  Queued mail for AFOTEC.ARPA.#Internet using TCP failed.

--Frank
20-Nov-87 02:40:04-PST,613;000000000001
Mail-From: KLH created at 20-Nov-87 02:37:25
Date: Fri, 20 Nov 87 02:37:21 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Linking assembler subroutines with KCC programs
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

What you tried sounds as if it should work, but you say that printf
acts strangely, which sounds like a bug of some kind.  Could you send
a small program that demonstrates the problem?  Using #asm/#endasm is
usually best, by the way.
-------
20-Nov-87 10:45:26-PST,2181;000000000001
Received: from CU20B.COLUMBIA.EDU by SRI-NIC.ARPA with TCP; Fri 20 Nov 87 10:41:04-PST
Date: Fri 20 Nov 87 13:41:06-EST
From: Ken Rossman <[email protected]>
Subject: Re: Linking assembler subroutines with KCC programs
To: [email protected]
cc: [email protected]
Address: 715 Watson Labs, 612 W. 115th St, NY NY 10025
Phone: (212) 280-4876
Message-ID: <[email protected]>

  Could you send a small program that demonstrates the problem?

The code I have right now is pretty large, and I don't want to try to hack
it down right now into something small that reproduces the problem for you
(nor do I think you really want to see all the code I have).

  What you tried sounds as if it should work, but you say that printf acts
  strangely, which sounds like a bug of some kind.

I think I may have the key to the problem.  I do some LOCing in the source
to move to a page boundary (the MACRO code I am writing does paged IPCF).
I suspect that having this code land in the DATA segment, and then doing a
LOC to move to a new page boundary might cause my data to overlay some
other area that KCC thinks is free space or something...

I don't do any RELOCing at all (yet), to pop between sections, as the MACRO
code that KCC generates does.  I'm using that now as a guide.

My question is not only why does printf stop working, but also why does
MACRO CODE get stuffed into the DATA segment.  I'm guessing it's because
in the absence of any RELOC's in my MACRO source, I automatically get
stuffed down at 140, instead of up in 400000+ somewhere...

I'm experimenting further, and will let you know what I find.

  Using #asm/#endasm is usually best, by the way.

I have, in fact, gotten the program to work by nesting my MACRO code in a C
subroutine.  But I guess I was just curious to find out why I couldn't just
write my own MACRO subroutine in a separate module and link it with other
KCC modules.  I think I am close to figuring out how to do this now.  /Ken

P.S. -- A (hopefully more or less) general KCC paged IPCF package may come
out of all of this.  If so, are you interested in the code?
-------
22-Nov-87 13:56:14-PST,485;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sun 22 Nov 87 13:52:40-PST
Date: Sun, 22 Nov 1987  14:52 MST
Message-ID: <[email protected]>
From: [email protected]
To:   [email protected]
cc:   [email protected]
Subject: STIW% and EPCAP%

If RAW mode is requested, then the STIW% (not checked for failure)
will fail unless EPCAP% is used to turn on ^C capability.  See
TELNET.MAC at label CAPINI: for the right way to do it.

--Frank
23-Nov-87 22:31:54-PST,1840;000000000001
Received: from CU20B.COLUMBIA.EDU by SRI-NIC.ARPA with TCP; Mon 23 Nov 87 22:27:34-PST
Date: Tue 24 Nov 87 01:27:06-EST
From: Ken Rossman <[email protected]>
Subject: storage allocation
To: [email protected]
Address: 715 Watson Labs, 612 W. 115th St, NY NY 10025
Phone: (212) 280-4876
Message-ID: <[email protected]>

Seems doing anything with LOC is big trouble in a KCC/assembler combination
source.  I always kind of thought that doing something like:

	loc <.+1000>&777000

would put you up at the next page boundary (or maybe I'm missing
something).  In any case, instead in a KCC program, this seems to put me at
the BEGINNING of the CURRENT page instead, which causes whatever storage
that was there beforehand to get overlaid, of course (and if it's in the
DATA segment, this seems to affect PRINTF in various funny ways).
Something about the way RELOC works is evading me, I guess...

I still don't know what's going on exactly, but so far have worked around
it with various kludges (like leaving large chunks of deadwood storage
between things, leaving my data up with my assembly code, etc).  Know of
any good way to define storage to start on a page boundary from within KCC?
I suppose if I could do that, I could probably avoid using assembly
language altogether.

In any case, I don't want to sound like all trouble here.  I did want to
mention that I am immensely enjoying coding in KCC.  It's particularly a
joy to be able to write REAL system programs in C on a DEC-20, especially
when you've just spent the past 8-9 years coding only in MACRO.  I'm
finding KCC to be quite complete, and quite intelligently designed around a
machine that doesn't necessarily easily lend itself to good C
implementations.  To my mind, KCC wins big here.

/Ken
-------
24-Nov-87 12:04:33-PST,1165;000000000001
Mail-From: KLH created at 24-Nov-87 12:00:43
Date: Tue, 24 Nov 87 11:53:45 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: storage allocation
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

No, you can't force static storage to be aligned on a page boundary.
The output MUST be in relocatable format for the linker to have a chance;
attempting to use absolute-assembly things like LOC will just overlay
something that the linker puts there.

What you can do is either:
(1) use a very large static array (at least 2 pages long) and at run time
derive a pointer to the first page boundary within that array.

(2) use dynamic allocation, i.e. make a call to malloc() for the number
of pages you want, plus one, and then derive a pointer to the first
page boundary in the same way as for (1).

The C runtime avoids pages 770-777 inclusive (for those misguided people
who like old-fashioned IDDT) but everything else is subject to clobberage
unless explictly allocated by declarations or malloc().
-------
24-Nov-87 12:24:25-PST,800;000000000001
Mail-From: IAN created at 24-Nov-87 12:17:47
Date: Tue, 24 Nov 87 12:17:35 PST
From: Ian Macky <[email protected]>
Subject: Re: storage allocation
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

    (2) use dynamic allocation, i.e. make a call to malloc() for the number
    of pages you want, plus one, and then derive a pointer to the first
    page boundary in the same way as for (1).

Also, there are nonstandard page allocation/freeing routines included in
malloc.  _palloc(n) allocates n pages, returning the page# of the first
page; _pfree() on that page# frees the pages.  Internally this works the
same way as (2) above, it just does it for you.
-------
25-Nov-87 20:46:07-PST,1853;000000000001
Received: from CU20B.COLUMBIA.EDU by SRI-NIC.ARPA with TCP; Wed 25 Nov 87 20:40:24-PST
Date: Wed 25 Nov 87 23:40:16-EST
From: Ken Rossman <[email protected]>
Subject: TOPS-20 internal date/time vs unix internal date/time
To: [email protected]
Address: 715 Watson Labs, 612 W. 115th St, NY NY 10025
Phone: (212) 280-4876
Message-ID: <[email protected]>

Why doesn't the following seem to work right?  As I understand the
following sequence, I'm getting a TOPS-20 IDT, and converting it to a
unix-internal format with tadl_to_utime.  I should then be able to get the
internal numbers broken down with localtime, no?

            --------------------------------------------------


#include <stdio.h>
#include <jsys.h>
#include <sys/time.h>
char *ctime();

main()
{
    time_t uidt;                        /* unix idt stg */
    int acs[16];                        /* jsys acs */
    struct tm *lt;                      /* internal unix time breakdown */

    jsys(GTAD,acs);                     /* get current date/time */

    uidt = tadl_to_utime(acs[1]);       /* make internal UNIX time */
    lt = localtime(uidt);               /* break down to separate #'s */
    printf("uidt:  %d\n",uidt);
    printf("exp:   %s",ctime(uidt));
    printf("sec:   %d\n",lt->tm_sec);
    printf("min:   %d\n",lt->tm_min);
    printf("hour:  %d\n",lt->tm_hour);
    printf("mday:  %d\n",lt->tm_mday);
    printf("mon:   %d\n",lt->tm_mon);
    printf("year:  %d\n",lt->tm_year);
    printf("wday:  %d\n",lt->tm_wday);
    printf("yday:  %d\n",lt->tm_yday);
    printf("isdst: %d\n",lt->tm_isdst);
}

                 ----------------------------------------

Also, unless I'm mistaken, LIBC.DOC has the definitions of tadl_to_utime()
and tadl_from_utime() reversed.

/Ken
-------
26-Nov-87 10:21:11-PST,764;000000000001
Mail-From: IAN created at 26-Nov-87 10:18:36
Date: Thu, 26 Nov 87 10:18:34 PST
From: Ian Macky <[email protected]>
Subject: Re: TOPS-20 internal date/time vs unix internal date/time
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

    time_t uidt;                        /* unix idt stg */
    struct tm *lt;                      /* internal unix time breakdown */
	. . .
    uidt = tadl_to_utime(acs[1]);       /* make internal UNIX time */
    lt = localtime(uidt);               /* break down to separate #'s */

localtime takes a POINTER to a time_t as it's arg.  who knows why?  i've
made the same mistake myself...

--ian
-------
29-Nov-87 15:36:02-PST,1112;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sun 29 Nov 87 15:31:44-PST
Date: Sun, 29 Nov 1987  16:31 MST
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: Using a free()'d ptr in realloc()

Although CARM (11.4.4 - first ed.) explicitly disallows (in effect) the
use of a free()'d ptr in a subsequent realloc(), I have found some
code which does use it for what is called "memory compaction."  In the
Unix SYSV manual under malloc(), it says:

    "Realloc also works if ptr points to a block freed since the last
    call of malloc, realloc, or calloc; thus sequences of free, malloc
    and realloc can exploit the search strategy of malloc to do
    storage compaction."

What, then, would be the equivalent KCC/CARM sequence to the following?

char *ralloc(p,n)	/*compacting reallocation */
char *p;
{
	register char *q;
	char *realloc();
	free(p);
	free(dummy);
	dummy = malloc(1);
	q = realloc(p, (unsigned)n);
	if(q==NULL)
		noroom();
	return(q);
}
30-Nov-87 14:41:38-PST,1096;000000000001
Mail-From: KLH created at 30-Nov-87 14:37:54
Date: Mon, 30 Nov 87 14:37:40 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Using a free()'d ptr in realloc()
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

I'm not sure what the "dummy" variable in your code refers to.  But at
any rate, that quote from the UPM refers ONLY to that particular system;
it is highly non-portable and dangerous to rely on anything like that.
Here is a quote from the ANSI C draft standard Rationale (not part of
the standard itself, but serving as explanatory material):

The "free()" function:

	The Standard makes it clear that a program may only free that which
	has been allocated, that an allocation may only be freed once, and that
	a region may not be accessed once it is freed.  Some implementations
	allow more dangerous license.  The null pointer is specified as a
	valid argument to this function to reduce the need for special-case
	coding.

-------
 4-Dec-87 13:08:57-PST,1049;000000000001
Mail-From: HSS created at  4-Dec-87 13:05:10
Date: Fri, 4 Dec 87 13:05:05 PST
From: Harry Sameshima <[email protected]>
Subject: 2d arrays in C
To: [email protected]
Message-ID: <[email protected]>

The only difference between the following programs is the definition
of the xyzzy array.....


[PHOTO:  Recording initiated  Thu 3-Dec-87 6:20pm]

@ty test1.c
#include <stdio.h>
main()
{
int	i;
char	xyzzy[5][4];

	strcpy(xyzzy,"bif");
	strcpy(xyzzy+1,"foo");
	strcpy(xyzzy+2,"bar");
	strcpy(xyzzy+3,"baz");
	strcpy(xyzzy+4,"bin"); 

	for (i=0;i<5;++i)
		printf("%s\n",xyzzy+i);
}
@test1
bif
foo
bar
baz
bin
@ty test2.c
#include <stdio.h>
main()
{
int	i;
char	xyzzy[5][5];

	strcpy(xyzzy,"bif");
	strcpy(xyzzy+1,"foo");
	strcpy(xyzzy+2,"bar");
	strcpy(xyzzy+3,"baz");
	strcpy(xyzzy+4,"bin"); 

	for (i=0;i<5;++i)
		printf("%s\n",xyzzy+i);
}
@test2
?Illegal instruction 0 at .UIOTY+55
?Undefined operation code
@pop

[PHOTO:  Recording terminated Thu 3-Dec-87 6:21pm]

-------
 4-Dec-87 17:19:05-PST,818;000000000001
Mail-From: KLH created at  4-Dec-87 17:17:12
Date: Fri, 4 Dec 87 17:17:08 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: 2d arrays in C
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Congratulations on a good demo program.  It turns out there was a bug
in the way KCC handled

	(a) incomplete pointer references to
	(b) multi-dimensional
	(c) char arrays
	(d) when adding an integer.

I've fixed it, but have not installed the new version yet as I am
still hoping to get around to fixing the macro processor.  It seems to
be a relatively difficult bug to provoke (as illustrated by the
conditions), but if you need the latest version, let me know.

Thanks,
--Ken
-------
15-Dec-87 07:39:12-PST,494;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Tue 15 Dec 87 07:34:36-PST
Date: Tue, 15 Dec 1987  08:34 MST
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: Apparent problem with rename()

It *appears* that rename() does not release the jfn of the "to" file
which eventually results in program failure because no more jfns are
available for the job.

--Frank
16-Dec-87 12:45:07-PST,2861;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Wed 16 Dec 87 11:46:14-PST
Date: Wed, 16 Dec 1987  14:02 EST
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   Mark Crispin <[email protected]>, [email protected]
Cc:   [email protected], Peter Karp <[email protected]>,
      [email protected]
Reply-To: [email protected]
Subject: tops-20 resolver
In-reply-to: Msg of 15 Dec 1987  18:15-EST from Mark Crispin <[email protected]>

    Date: Tuesday, 15 December 1987  18:15-EST
    From: Mark Crispin <[email protected]>

         I just restarted Chives.  It had between 719/2 to 781/2 pages in its
    working set.  In its memory map, it was using pages 0 and 1 in section 0,
    pages 0-2,6,10-14,32 (private) and 15-31,400-455 (public) in section 1,
    pages 0,777 (read-only) and pages 1-13 (read/write) in section 2, all of
    sections 3 and 4, and pages 0-71 in section 5.

         The working set of Chives, just after loading the zone files, is 266/2
    pages.

         Working set numbers are as reported by SYSDPY.

Sections 0, 1, & 2 are ok (buffers for JSYS calls that lose on 30 bit
addresses, static data/pure code, and stack respectively).  From
section three up is malloc() space.  CHIVES is a memory hog but I
really don't think it uses THAT much space, certainly not in just a
few days with only two zones loaded.

So, that does indeed sound like malloc() isn't getting things off the
freelist correctly.  I tried tracking this down once but it's a real
bear, and of course it doesn't happen to simple test programs.  It is
possible to force a CHIVES crashdump then call a couple of MALLOC.C
diagnostic routines to look at the freelist, but it's not much fun.

         I suggest you simply never call free() at all, and just maintain your
    own freelists of well-known block sizes.  Call malloc() only when you need a
    block of a size that isn't on the freelist.  Eventually, Chives should max
    out with the maximum case free storage usage.

Another option would be to replace the MALLOC module entirely for
CHIVES.  This would allow me to do area based memory allocation and
would make a real garbage collector possible.  Note that the KCC
runtimes themselves use malloc() and free(), so things will probably
break eventually unless they are fixed or replaced.

The bad news is that if I have to spend a lot of time on this I'm
going to miss the Christmas deadline I announced last week.  Bletch.

Ken, Ian, have you seen anything like this?  Do you know of any other
cases of people using a KCC program as a system daemon that does a lot
of memory allocation/deallocation and stays running for days or weeks
at a time?

--Rob
16-Dec-87 21:20:31-PST,3042;000000000001
Mail-From: KLH created at 16-Dec-87 21:15:28
Date: Wed, 16 Dec 87 21:14:11 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: tops-20 resolver
To: [email protected], [email protected],
    [email protected]
cc: [email protected], [email protected],
    [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

No, I haven't seen this kind of thing.  The closest might be KCC itself,
which must reclaim everything between file compilations (when it has many
filename arguments in a single invocation); this had problems at one time
but was fixed -- too far back to remember whether malloc or KCC was at
fault.

I don't know what data structures you are using, but having 2+
sections for data doesn't strike me as particularly extraordinary.
Note that what you see in terms of page allocation will always
represent the MAXIMUM high-water mark during the program's lifetime,
since free() does not try to flush unused pages from the page map.
The thing to remember about malloc/free is that once an area is
malloced, no matter how small it is or what it is used for, it cannot
ever be compacted (unless freed) since the library code has no way of
knowing whether it's safe to move.  So certain sequences of
allocations can end up using much larger portions of memory than you
might expect.  Fragmentation.  If you tend to allocate very large
chunks at a time, you will have very large portions of unused space
too.

One thing you can do easily is check your malloc.c against the latest
one here:
	SS:<KCC-4.LIB>MALLOC.C

If there is no difference (very probable) then you will just have to
add some instrumentation.  Making your code call private routines like
"chkalloc" and "chkfree", which can call malloc/free after gathering
some statistics, will let you determine whether something is in fact
wrong.  A simple test I have used in the past is to keep a counter of
successful malloc calls which is decremented by non-null free calls;
its value at any time is the number of outstanding malloc'd blocks.
If this number increases slowly over time it tells you that your
program is failing to free up something.

For highest storage efficiency you may well have to add your own second-level
allocation strategy, but this just makes the alloc/free process faster when
dealing with blocks of standard sizes.  It doesn't help you if your program
already does something incorrectly.

Provoking a crash dump and listing out the memory usage is an
excellent idea.  Providing a way to query the usage without crashing a
running program is an even better idea (I do this in my editor, which
has an extremely complicated allocation package).  Before you embark
on something as ambitious as yet another whiz-bang storage allocator,
I suggest you endure the very much smaller pain of looking at the
memory usage output (from _free_list() and _memory_map()).

--Ken
-------
16-Dec-87 22:35:10-PST,473;000000000001
Mail-From: KLH created at 16-Dec-87 22:32:23
Date: Wed, 16 Dec 87 22:31:32 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Apparent problem with rename()
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

You are correct.  rename() was failing to free the new JFN.  I have
installed a new version of C:LIBC.REL with the fix.
-------
 3-Jan-88 22:29:37-PST,874;000000000001
Mail-From: TODD created at  3-Jan-88 22:27:27
Date: Sun, 3 Jan 88 22:27:24 PST
From: Todd Koumrian <[email protected]>
Subject: FSEEK and FREAD broken
To: [email protected]
cc: [email protected]
Location: SRI-International  Room EK205, Phone: (415)859-5921
Message-ID: <[email protected]>

Either FSEEK or FREAD is broken, although I can not be sure which.
A test program is available as PS:<TODD>FTEST.C to demonstrate the problem.

After FSEEK'ing to a particular spot, (FTELL "verifies that I'm where I
want to be), FREAD'ing does not read from that place.

My test program takes a single argument, a filename of a text file.  It then
copies the first 2600 characters to a file it creates called "BARF.TXT",
by FSEEK'ing and then FREAD'ing in small chunks.  It gets pretty wild
after a while; give it a try.

Todd Koumrian
-------
 4-Jan-88 11:51:43-PST,665;000000000001
Mail-From: KLH created at  4-Jan-88 11:51:25
Date: Mon, 4 Jan 88 11:51:11 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: FSEEK and FREAD broken
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

The problem is with your program.  See the documentation for fseek/ftell
in H&S (2nd ed), page 315.  Note particularly the sentence at the bottom,
and the examples at the top of the next page.

You cannot fseek to arbitrary locations on a text stream.  You can only
seek to 0, EOF, or a location previously returned by ftell.
-------
 5-Jan-88 15:03:15-PST,2267;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Tue 5 Jan 88 14:58:23-PST
Date: Tue, 5 Jan 1988  17:39 EST
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
cc:   [email protected], [email protected]
Subject: PSECT support for KCC

So, after the tenth time I found myself cursing the inability of KCC
and the common MACRO libraries (particularly HSTNAM) to interoperate,
I decided to write PSECT support for KCC.  It turns out to be pretty
trivial.  The changes consist of:

- A new module to be loaded before anything else (like C:LIBCKX, which
  this module must precede) which is entirely .PSECT, .ENDPS, and
  .TEXT pseudos to set things up properly.  36 lines total code, half
  of it comments.

- A trailer module which defines the end-of-psect tags.  Two lines.

- About ten lines of code added to CRT.C.  This was the only hard
  part.  It turns out that LINK does completely different things for
  PSECTed programs, even when they have the magic "turn my TWOSEG
  program into a PSECTed program" switch enabled.  It's not very hard
  to handle though, since SSTART can determine whether it was loaded
  with PSECTs or not by looking at the JOBDAT stuff it'd have to look
  at anyway.

I used the /REDIRECT switch that was invented for the benefit of
FORTRAN-10 and other compilers that need to load TWOSEG libraries with
PSECT programs.  I used an obscure LINK switch to make sure that the
trailer module is the very last thing loaded (this is the same trick I
used to solve the same problem in the Stanford user FTP program).

As an additional benefit, you get the code segment write-protected.
The new CRT code knows to round up to the next page boundry so that
malloc() won't barf.

I haven't tested this code extensively yet, but HELLO.C runs ok, so
the low level stuff (including malloc()) works.

I'll probably end up calling the two automaticly generated PSECTS
"CODE" and "DATA" (hiseg and loseg, respectively), since the MACRO
libraries I'm most interested in using all follow the PSECT naming
conventions MRC laid down for the Stanford user network programs.

If you're interested in this stuff, holler.

--Rob

-------
 5-Jan-88 15:58:13-PST,1254;000000000001
Mail-From: KLH created at  5-Jan-88 15:55:41
Date: Tue, 5 Jan 88 15:55:37 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: PSECT support for KCC
To: [email protected], [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

I don't think compatibility with existing MACRO libraries is a
particularly useful feature (they could be redone in C).  However, the
ability to force LINK to put the code and data segments in specific
places, particularly in section 1 (obviating the need for the silly
runtime re-map) would be quite handy.  In theory there is a LINK
switch to allow this for conventional loseg and hiseg stuff, but it
doesn't work -- it always sets the hiseg origin to 400000.  Snarl.

Can the changes be made conditional on a KCC switch, similar to -i?
Can FAIL still be used to assemble user modules?  If so, there should
be no problem integrating this into the distribution version; please
send the stuff, and I'll send you comments, and we'll iterate.

Note that all code and static data must still fit completely within one
section of memory.  The code KCC generates will not work otherwise.
-------
 5-Jan-88 16:28:13-PST,2113;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Tue 5 Jan 88 16:23:13-PST
Date: Tue 5 Jan 88 19:22:34-EST
From: Rob Austein <[email protected]>
Subject: Re: PSECT support for KCC
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

The files are in XX:<SRA.77>.  You want CPSECT.MAC (sic), CENDPS.C,
and CRT.C.

My interest in being compatable with existing MACRO libraries stems
from extreme frustration at trying to keep parallel versions
consistant when we have a perfectly good linking loader that's
supposed to be able to solve all these problems for us.  I want the C
code (which will be installed, on XX anyway, as C:LIBsomething.REL) to
be able to load whatever the current latest and greatest HSTNAM.REL
is, straight out of the MMAILR distribution.  The C code will just be
something to translate between calling conventions.  Or I might even
just write a single routine that translates between the normal MACRO
calling conventions (args/vals in AC1->AC4, +1/+2 return) and C
conventions, sort of like jsys().  Reimplementing the same code in
multiple languages is a huge waste of time that I can't afford.

I agree that making extended .EXEs directly would be nice.  The CRT changes
should free you from some of the LINK randomness; the only JOBDAT symbol
used by the PSECT version is .JBSA, and that's only used so that we can
safely include the symbol table at the end of the code segment.

There shouldn't be any problem with handling this stuff like -i, that's
why the modules are set up as they are.  Nor should there be any problem
with using FAIL for user modules, although I can't see why anyone would
want to (I know, ancient history).  All the static data and code
still fits in a single section; in fact, the only difference in the
memory layout in my initial version of the PSECT code is that
the low segment begins at 1000 instead of 140 so that the DATA
psect can start on a page boundry (LINK gets -very- upset otherwise).
-------
 5-Jan-88 19:48:18-PST,830;000000000001
Received: from SUMEX-AIM.Stanford.EDU by SRI-NIC.ARPA with TCP; Tue 5 Jan 88 19:44:46-PST
Received: from PANDA.PANDA.COM by SUMEX-AIM.Stanford.EDU with Cafard; Tue, 5 Jan 88 19:39:13 PST
Date: Tue, 5 Jan 88 18:32:07 PST
From: Mark Crispin <[email protected]>
Subject: Re: PSECT support for KCC
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Postal-Address: 1802 Hackett Ave.; Mountain View, CA  94043-4431
Phone: +1 (415) 968-1052
Message-ID: <[email protected]>

I applaud Rob's effort to get PSECT support into KCC, and I hope it
gets adopted into the next release of KCC.  PSECTs are damn useful,
and the leading reason I don't use FAIL or MIDAS is their lack of
support for PSECTs.

When will the next KCC be released, anyway?
-------
 5-Jan-88 19:58:18-PST,1270;000000000001
Received: from SUMEX-AIM.Stanford.EDU by SRI-NIC.ARPA with TCP; Tue 5 Jan 88 19:56:39-PST
Received: from PANDA.PANDA.COM by SUMEX-AIM.Stanford.EDU with Cafard; Tue, 5 Jan 88 19:51:38 PST
Date: Tue, 5 Jan 88 18:39:17 PST
From: Mark Crispin <[email protected]>
Subject: Re: PSECT support for KCC
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Postal-Address: 1802 Hackett Ave.; Mountain View, CA  94043-4431
Phone: +1 (415) 968-1052
Message-ID: <[email protected]>

Ken -

     While we're snarling, will there ever be a version of KCC that
generates REL files directly instead of using an assembler?  The 6
character symbol name limitation is a pain, even though it is blessed
by ANSI.

     I suggest also that you consider using MACRO as the default
assembler instead of FAIL.  Several KCC sites already patch TGASM
to get around FAIL lossages.  Like MIDAS, FAIL was a win long ago,
but it seems to be an idea whose time has past...

     Will you be interested in looking at C Logo some time?  I still
can't get a working version built under KCC, but it did build under
PCC.  I'm willing to try again with KCC-4 once you release it.

-- Mark --
-------
 6-Jan-88 12:53:49-PST,2258;000000000001
Mail-From: KLH created at  6-Jan-88 12:53:08
Date: Wed, 6 Jan 88 12:53:01 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: PSECT support for KCC
To: mrc%[email protected]
cc: [email protected], [email protected], [email protected]
Message-ID: <[email protected]>

I don't know when the KCC-4 version will be absolutely complete.  What
is holding things up is a minor problem with the C preprocessor.  If I
had a few uninterrupted days I could fix it, but things will continue
to be VERY bad here until the end of January (official work takes
priority).  The library is fine, and the binary compiler is fine, the
only issue is that of making the compiler source consistent with the
working binary.  If you want to use it anyway (after all, that's what
we're doing here) you can get everything from SS:<KCC-4> plus
SYS:CC.EXE.0.

I like the idea of producing .REL files, but doubt it will happen
soon, unless someone wants to specifically pay for it.  There are more
important problems like adding function prototypes.  The 6 char
external limitation keeps coming up, but none of the other facts
change -- to ensure your code is portable you MUST make externals
unique in the first 6 monocase chars.  Whether your own system, or
TOPS-20, supports longer names is irrelevant; you can't know what
other systems are out there that might depend on this.  If you want
to import outside software that isn't as portable as it should be, or
want to use long identifiers for your own pleasure, you can #define
them to something short and unique (standard method).  If you want to
use longer names for debugging, well, you'll have to upgrade IDDT (or
something) to understand the new symbol table format.

As for the choice of assembler, our own default is FAIL, and we don't
waste our time trying to make the distribution different from what we
actually run.  Other sites are free to use a switch, or recompile, or
patch tgasm (it's documented).

As you might guess, there is no time to look at other programs such as
C Logo (however, if you have money... :-) I do think, though, that the
KCC-4 library will solve just about all of the problems you were
previously having.

--Ken
-------
 6-Jan-88 22:31:50-PST,1142;000000000001
Received: from SUMEX-AIM.Stanford.EDU by SRI-NIC.ARPA with TCP; Wed 6 Jan 88 22:28:43-PST
Received: from PANDA.PANDA.COM by SUMEX-AIM.Stanford.EDU with Cafard; Wed, 6 Jan 88 14:56:28 PST
Date: Wed, 6 Jan 88 14:12:11 PST
From: Mark Crispin <[email protected]>
Subject: Re: PSECT support for KCC
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Postal-Address: 1802 Hackett Ave.; Mountain View, CA  94043-4431
Phone: +1 (415) 968-1052
Message-ID: <[email protected]>

     Thanks for your note.  I understand completely.  I hope you
understood my minor grumbles as "wish list" items from someone
who is not a C programmer and hopes never to become one!

     Most of the time, when faced with such portability problems,
I've ended up reimplementing it in DEC-20 assembly language than
spend the same time (or longer) fixing the portability problems.

     I believe DEC DDT already understands long symbol names.
Very few of us use IDDT any more; it's too incompatible from the
DDT that is used for everything else.

-- Mark --
-------
 9-Jan-88 20:29:16-PST,1820;000000000001
Received: from SCIENCE.UTAH.EDU by SRI-NIC.ARPA with TCP; Sat 9 Jan 88 20:25:46-PST
Date: Sat 9 Jan 88 21:26:27-MST
From: Pieter <[email protected]>
Subject: Two bugs in KCC
To: [email protected]
cc: [email protected]
US-Mail: "Center for Scientific Computation, 210 South Physics, University of Utah, Salt Lake City, UT 84112"
Telephone: (801) 581-8125
Message-ID: <[email protected]>

The following program demonstrates 2 bugs I have found in KCC
(version of about 17-Sep-87):

    1.	In the for loop in the function foo with -O=all (the default)
	The optimization is done incorrectly.  The "i++" is done even
	if the if statement is true.  This causes the value of i to
	be incorrect when used farther down.  Turning off any part
	of the optimization corrects this problem, but only in this
	simple program (not the real one I am working on).

    2.	When all optimization is turned off the for loop in main is
	done incorrectly.  The instruction "jumpe 1,foo" (where foo is
	after the loop) is placed at the top of the loop which can
	cause the loop to be terminated incorrectly.
	

------------------------------------------------------------
#  define howmany(x, y) (((x)+((y)-1))/(y))
#define FD_SETSIZE 32
#define NFDBITS (sizeof(int)*8)

int func()
{
	return (NFDBITS);
}


int foo()
{
	int i,w;

	for (w = 0, i = 0; i < howmany(FD_SETSIZE, NFDBITS); i++) {
	    if ((w = func()) > 0)
		break;
	}
	if (w < 1)
	    return(-1);
	w += (i*NFDBITS) - 1;
	return ((w > FD_SETSIZE) ? -1 : w);
}

void main()
{
	for (;;) {
	    printf("foo = %d\n", foo());
	}
}
------------------------------------------------------------

  If more information is needed please let me know.

Pieter
[email protected]
-------
13-Jan-88 14:50:58-PST,640;000000000001
Mail-From: KLH created at 13-Jan-88 14:32:16
Date: Wed, 13 Jan 88 14:31:56 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Two bugs in KCC
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Thanks for your bug report.  I've found and fixed both problems.
You can get the new binary by FTPing SYS:CC.EXE from SRI-NIC.

(Internal gist: The first was a problem with crossjump() passing over
AOS/SOS and the second came about because gfor() was calling
gboolean() with a null pointer.)
-------
18-Jan-88 19:40:09-PST,507;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 18 Jan 88 19:35:55-PST
Date: Mon, 18 Jan 1988  20:35 MST
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: Problem with getchar()

With CC (583) and LIBC (207):

Both getchar() and getc(stdin) want a CR terminator before returning.
That CR is then read again for the next input!  What am I doing wrong
(again)?

--Frank
18-Jan-88 21:45:08-PST,935;000000000001
Mail-From: KLH created at 18-Jan-88 21:42:55
Date: Mon, 18 Jan 88 21:42:49 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Problem with getchar()
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

I don't know.  I tried the following test program, which worked just
as it should:

#include <stdio.h>
main()
{	int c;
	while ((c = getchar()) != EOF)
		printf(" %o", c);
}

When you type to this program, the line-buffered input should all be
printed when you type CR, along with a trailing LF (12).  There is no
CR character (15) in the input.  The monitor turns a typed CR into
CR+LF; the read() call transforms CR+LF into just LF.

Try this on your system, just for kicks.  If you can't figure it out,
tell me more of the context (but let's take it off bug-kcc).

--Ken
-------
23-Jan-88 06:45:33-PST,956;000000000011
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sat 23 Jan 88 06:44:44-PST
Date: Sat, 23 Jan 1988  07:44 MST
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: Revised Last Write algorithm for mtime

The current algorithm in stat() (actually _stat()) picks among .FBCRE,
.FBCRV, and .FBWRT for what to return as st_mtime.  We often upload
files and use utime() to set the last write of the file to correspond
to the same info on the PC copy of the file.  That time is always
BEFORE the time the file is created (.FBCRE and .FBCRV according to
TOPS-20).  However, utime() only sets .FBWRT.  The problem is that
stat() will end up always returning .FBCRE as the st_mtime, which is
wrong from our point of view.

The revised algorithm requested for stat() is to always return .FBWRT
as the value for st_mtime.

--Frank
 2-Feb-88 01:44:03-PST,491;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Tue 2 Feb 88 01:41:52-PST
Date: Tue, 2 Feb 1988  02:41 MST
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: Bug with CC(583)

Compile this to see bug:

#define UNC 25
#define NCAP 32

struct prncode {
	char *prncap[NCAP][10];
} printer;

prnunl ()
{
    char *s2;

        s2=printer.prncap[UNC];
}
 7-Feb-88 13:44:22-PST,855;000000000001
Mail-From: KLH created at  7-Feb-88 13:42:00
Date: Sun, 7 Feb 88 13:41:57 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Bug with CC(583)
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Thanks, I've fixed the bug.  It was triggered when KCC attempted to apply
an implicit conversion to this particular case; if you used an explicit cast
to (char *) then it would have worked without complaint.  Note that a cast
is needed because printer.prncap[n] is NOT a char pointer; it is a pointer
to an array of char pointers.  So your code may not be doing what you think
it is doing.

Since I'm doing another change at the moment, I haven't installed the new
version.  I'll let you know when it's ready.
-------
22-Feb-88 14:24:02-PST,2917;000000000000
Received: from SCIENCE.UTAH.EDU by SRI-NIC.ARPA with TCP; Mon 22 Feb 88 14:19:19-PST
Date: Mon 22 Feb 88 15:18:49-MST
From: Pieter <[email protected]>
Subject: sizeof problem
To: [email protected]
cc: [email protected]
US-Mail: "Center for Scientific Computation, 210 South Physics, University of Utah, Salt Lake City, UT 84112"
Telephone: (801) 581-8125
Message-ID: <[email protected]>

    I have run across a minor problem with the sizeof operator
in KCC (of 13-Jan-88).  When taking the sizeof an array of
char the correct number of bytes is returned, but when the
array is a member of a structure the value returned by sizeof
is always four (probably returning the sizeof a pointer).
I was unsure if KCC was correct, or I was correct about what
should have been returned, so I ran a test program using VAX C
and Sun C, both returned the number of bytes in the array.
H&S and the ANSI draft (Oct or some such date) specify the
number of bytes in the array not the pointer size.

    I'm including a test example (which is very much like a
program which was posted in INFO-C).

Pieter
Arpa: [email protected]
------------------------------------------------------------
#include <stdio.h>

struct {
    unsigned a : 4;
    unsigned b : 4;
    unsigned c : 6;
    int d;
    char e;
    char f[5];
    short g;
} foo = {1, 2, 3, 4, '5', "1234", 24};

void test(f, d, s, c, a)
    float f;
    double d;
    short s;
    char c;
    int a[10];
{
    auto float af;
    auto double ad;
    auto short as;
    auto char ac;
    auto int aa[10];

    fprintf(stdout,
        "sizeof args:   float=%d  double=%d  short=%d  char=%d  int[10]=%d\n",
        (int)sizeof(f), (int)sizeof(d), (int)sizeof(s),
        (int)sizeof(c), (int)sizeof(a));
    fprintf(stdout,
        "sizeof autos:  float=%d  double=%d  short=%d  char=%d  int[10]=%d\n",
        (int)sizeof(af), (int)sizeof(ad), (int)sizeof(as),
        (int)sizeof(ac), (int)sizeof(aa));
    fprintf(stdout,
        "sizeof struct:  foo=%d  a=%d  b=%d  c=%d  d=%d  e=%d  f=%d  g=%d\n",
        (int)sizeof(foo), (int)sizeof(foo.a), (int)sizeof(foo.b),
        (int)sizeof(foo.c), (int)sizeof(foo.d), (int)sizeof(foo.e),
	(int)sizeof(foo.f), (int)sizeof(foo.g));
}

int array[10];

void main()
{
    test(0., 0., 0, 0, array);
    fprintf(stdout,
        "struct foo:  a=%d  b=%d  c=%d  d=%d  e=%c  f=%s  g=%d\n",
        foo.a, foo.b, foo.c, foo.d, foo.e, foo.f, foo.g);
}
------------------------------------------------------------
sizeof args:   float=8  double=8  short=4  char=4  int[10]=4
sizeof autos:  float=4  double=8  short=2  char=1  int[10]=40
sizeof struct:  foo=24  a=0  b=0  c=0  d=4  e=1  f=4  g=2
struct foo:  a=1  b=2  c=3  d=4  e=5  f=1234  g=24
------------------------------------------------------------
-------
22-Feb-88 17:59:16-PST,864;000000000000
Mail-From: KLH created at 22-Feb-88 17:55:24
Date: Mon, 22 Feb 88 17:55:14 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: sizeof problem
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Yes, you've found a bug.  It turns out that sizeof's reversal of the
automatic conversion of array names to pointers is overlooking the case
where the array name is a structure member, because the conversion is
done differently.  It will take me a little while to make sure of how
best to fix this (array/function conversion has always been a headache,
since it is different from everything else); I'll let you know when a
new version is available (might be more than a week due to severe
proposal pressures here).
-------
28-Feb-88 03:35:25-PST,1659;000000000000
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Sun 28 Feb 88 03:34:50-PST
Date: Sat, 27 Feb 1988  19:31 EST
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: redirected stdout destroys existing files on "quota exceeded"

It seems that, if you redirect stdout to a disk file in a directory
that is at (or over) quota, KCC will quietly proceed to write and
CLOSF% an zero-length file.  This is a Very Bad Thing.  If it can't
write the file it should flame and abort, rather than destroying the
old copy of the file.  printf() isn't even returning an error when
this happens.  I expect that the problem also applies to fopen()'d
files, but I haven't checked.

[PHOTO:  Recording initiated  Sat 27-Feb-88 7:09PM]

 MIT TOPS-20 Command Processor 5(312161)-2
XX>fxnntp <$nntp$.grep
soc.women 15048 *BBOARD:SOC_WOMEN.TXT.1
rec.music.folk 1130 *BBOARD:REC_MUSIC_FOLK.TXT.1
rec.arts.comics 6178 *BBOARD:REC_ARTS_COMICS.TXT.1
news.lists 369 *BBOARD:NEWS_LISTS.TXT.1
news.groups 2661 *BBOARD:NEWS_GROUPS.TXT.1
news.config 467 *BBOARD:NEWS_CONFIG.TXT.1
news.announce.conferences 202 *BBOARD:NEWS_ANNOUNCE_CONFERENCES.TXT.1
news.admin 1655 *BBOARD:NEWS_ADMIN.TXT.1
XX>fxnntp <$nntp$.grep >bb:$nntp$.status
XX>i disk bb:
 XX:<BBOARD>
 5000 Pages assigned
 5000 Working pages, 5000 Permanent pages allowed
 14129 Pages free on XX:, 365871 pages used.
XX>v bb:$nntp$.status.0

   XX:<BBOARD>
 $NNTP$.STATUS.161;P777777   0 0(7)      27-Feb-88 19:10:50 SRA       
XX>pop

[PHOTO:  Recording terminated  Sat 27-Feb-88 7:11PM]
28-Feb-88 19:00:03-PST,1771;000000000000
Mail-From: KLH created at 28-Feb-88 18:55:27
Date: Sun, 28 Feb 88 18:55:21 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: redirected stdout destroys existing files on "quota exceeded"
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Well, what SHOULD happen?  "flame and abort" is imprecise.  ITS does
this much better -- it generates an interrupt which DDT knows about,
and you can proceed once you have freed up enough stuff.  This removes
the need for every program in the world to have its own
"check-for-overquota-error-and-tell-user-and-wait" routines.

In other words, this seems like a TOPS-20 problem to me.  How could
OPENF and CLOSF destroy a file, anyway?  If you have your gen-ret-count
set to 1, that's your mistake.

I agree the stdio functions should return an error if the output write()
fails, and the write() should fail if the SOUT%/BOUT% fails.  That,
I can look into later.  Note that most programs, however, never bother
to check the return value of putc or printf or any other output function.
Usual Unix brain damage.

Note that .ICQTA is bound to SIGXFSZ.  It isn't being triggered presumably
because an ERJMP turns the error condition into a simple error return.
I could, however, cause it to be invoked, and this could either
(1) call a user-defined signal handler, if one was specified by signal(),
or (2) as a default action, "flame and abort" (whatever you want that to be).
It could presumably ask the user whether to continue or not, although it
may be hard to know whether that makes sense (there may not be a "user" and
the channel to use may not be obvious either).
-------
28-Feb-88 19:25:03-PST,3104;000000000000
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Sun 28 Feb 88 19:21:11-PST
Date: Sun 28 Feb 88 22:20:25-EST
From: Rob Austein <[email protected]>
Subject: Re: redirected stdout destroys existing files on "quota exceeded"
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

    Date: Sun, 28 Feb 88 18:55:21 PST
    From: Ken Harrenstien <[email protected]>

    Well, what SHOULD happen?  "flame and abort" is imprecise.  ITS does
    this much better -- it generates an interrupt which DDT knows about,
    and you can proceed once you have freed up enough stuff.  This removes
    the need for every program in the world to have its own
    "check-for-overquota-error-and-tell-user-and-wait" routines.

    In other words, this seems like a TOPS-20 problem to me.  How could
    OPENF and CLOSF destroy a file, anyway?  If you have your gen-ret-count
    set to 1, that's your mistake.

I have the generation retention count set to six or something like
that.  But if a program runs under a batch job every few hours and
tells that batch job that it successfully completed and writes out a
new empty file each time, it will eventually cause the last good copy
of the file to disappear.  I suppose I could devote an entire disk
pack to the status files of this program so that I could keep a week's
worth around when I go on vacation, but that seems kind of excessive.

    I agree the stdio functions should return an error if the output write()
    fails, and the write() should fail if the SOUT%/BOUT% fails.  That,
    I can look into later.  Note that most programs, however, never bother
    to check the return value of putc or printf or any other output function.
    Usual Unix brain damage.

    Note that .ICQTA is bound to SIGXFSZ.  It isn't being triggered
    presumably because an ERJMP turns the error condition into a
    simple error return.  I could, however, cause it to be invoked,
    and this could either (1) call a user-defined signal handler, if
    one was specified by signal(), or (2) as a default action, "flame
    and abort" (whatever you want that to be).  It could presumably
    ask the user whether to continue or not, although it may be hard
    to know whether that makes sense (there may not be a "user" and
    the channel to use may not be obvious either).

Is it reasonable to say that if an output (write()) to a file failed,
the file should be closed with CZ%ABT?  Maybe not, this might screw
tape programs.

I'd settle for having the error status be reported by printf().  What
really got me was that there was nothing my program could have done
differently to detect the error so that it could abort().

Perhaps the right thing to do is call a handler routine if one was specified
by signal(), else just return an error code from write() back up through
printf().  I'm not familiar enough with the various unix signal() codes
to know if SIGXFSZ is the right one for this.
-------
 6-Mar-88 20:07:12-PST,2684;000000000000
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sun 6 Mar 88 19:55:33-PST
Date: Sun, 6 Mar 1988  20:54 MST
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: Some interesting problems

Just for fun, I tried compiling micro-emacs under KCC.  Of course,
there were the usual 6-char-limit fixes, and a couple of other
problems I'll get to in a minute.  However, after working around a
major stumbling block, I compiled an extended addressing version and
loaded it up with six buffers full of copies of TECO.MID before I quit
- I'm sure it can handle *much* more.  (I MEM showed some 5300 pages
in use when I finally got out.)  The screen display is fairly
reasonable and better, in some respects, than native EMACS.  It
doesn't make use of regional scrolling nor the insert/delete functions
of this terminal emulation (a vt102).

Now to the problems:

1.  KCC does not like #if constant where constant is not defined.  All
other C preprocessors appear to assume constant is 0 in that case.
CARM does not seem to directly address this case.

2.  I think there is a spurious warning generated in the case of:

typedef char *BITMAP;	/* in an include file */

static BITMAP clearbits();    /* in a global area */

	BITMAP clearbits();   /* in a function */
Storage class conflict for "clearbits"; assuming static

Should I be concerned?

3.  The stopper was that I chose to use termcap, and the program could
not get values returned for tgetnum for "li" or "co" except 0.  I
could not duplicate the problem in a modification of the TRMCAP.C TEST
case.  More on this when I find out more.  The temporary workaround
was to fix those values at 24 and 80, respectively.

4.  This program was compiled as a BSD environment.  One of the
options available is to suspend execution, berkeley style.  The
program aborted with the following error message:

?Fatal error in sigvec() PSI interrupt handler at PC = 1471272

471272 is PSIMSC+11 in the single-section version.

That's about it for now, except for one question: in the PC world,
they have various models, such as small, medium, large, etc., due to
the segment limitations of the 80x86 chip architecture.  What are the
equivalent model names as far as addressibility for KCC's single and
multi-section versions, if KCC were runnable in a PC environment?  (In
other words, is the single-section model already a larger address
space than the largest PC model, and if so, then what might you call
the multi-section model - some cute name, like "gigantic"?)

--Frank
 7-Mar-88 14:43:57-PST,2106;000000000000
Mail-From: KLH created at  7-Mar-88 14:37:45
Date: Mon, 7 Mar 88 14:37:22 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Some interesting problems
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

The problems first:

1. #if <undefined-name>
	As you say, CARM doesn't address this.  In the ANSI draft, they
are proposing that undefined identifiers evaluate to 0 in this context.
I personally think this is a bad idea, but I will modify KCC to proceed
after issuing a warning.

2. "Storage class conflict for "clearbits"; assuming static"
	This is a legitimate warning.  That function is being re-declared
with a different storage class (assumed-external instead of static).  KCC
is making a guess as to what was really intended.  Note that there is no
need for the second declaration given that the first one was global.

3. TERMCAP problem with tgetnum.
	My best guess is that those routines have a portability problem
which breaks them with multi-section programs.  Try the termcap test
program using extended addressing and see if this is so.

4. BSD execution suspension
	Exactly what does it invoke here?  I can fix this (at least one
form should be supported) but need a better idea what is going on.

Memory model name:
	Why not just use "single-section" and "multi-section".
Have you ever heard of a Navel or Valencia MacIntosh?

Other:
	One reason you find it possible to bring up Micro-emacs is because
I made sure KCC could support ELLE -- the emacs look-alike I wrote.  ELLE
doesn't need megabytes of memory; it can handle many buffers with files
of any size while remaining a small program.  I also added a couple things
for TOPS-20 so it could read files of byte sizes 7, 8, or 9, with or without
an EOL of LF or CRLF.  The real extensible EMACS is more powerful in general,
but ELLE is handy for huge or oddly formatted files, and as you've noticed
it's not too difficult to do redisplay better than EMACS.
-------
 7-Mar-88 15:12:18-PST,586;000000000000
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 7 Mar 88 15:10:58-PST
Date: Mon, 7 Mar 1988  16:10 MST
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   Ken Harrenstien <[email protected]>
Cc:   [email protected], [email protected]
Subject: TERMCAP problem with tgetnum
In-reply-to: Msg of 7 Mar 1988  15:37-MST from Ken Harrenstien <KLH at SRI-NIC.ARPA>

Ken,

Indeed, the termcap test failed ("no entry") when compiled either
standalone or with the -DTEST, both with extended addressing.

--Frank
 7-Mar-88 16:10:26-PST,1601;000000000000
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 7 Mar 88 15:30:28-PST
Date: Mon, 7 Mar 1988  16:30 MST
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   Ken Harrenstien <[email protected]>
Cc:   [email protected], [email protected]
Subject: BSD execution suspension problem
In-reply-to: Msg of 7 Mar 1988  15:37-MST from Ken Harrenstien <KLH at SRI-NIC.ARPA>

Ken,

I *think* these are the relevant code fragments.  Let me know if you
need more.

--Frank
--------------------

From termio.c, in ttopen():

#if     V7 | BSD
        gtty(0, &ostate);                       /* save old state */
        gtty(0, &nstate);                       /* get base of new state */
        nstate.sg_flags |= RAW;
        nstate.sg_flags &= ~(ECHO|CRMOD);       /* no echo for now... */
        stty(0, &nstate);                       /* set mode */
	ioctl(0, TIOCGETC, &otchars);		/* Save old characters */
	ioctl(0, TIOCSETC, &ntchars);		/* Place new character into K */
#if	BSD
	/* provide a smaller terminal output buffer so that
	   the type ahead detection works better (more often) */
	setbuffer(stdout, &tobuf[0], TBUFSIZ);
	signal(SIGTSTP,SIG_DFL);	/* set signals so that we can */
	signal(SIGCONT,rtfrmshell);	/* suspend & restart emacs */
#endif
#endif

From spawn.c:

#if	BSD

bktoshell()		/* suspend MicroEMACS and wait to wake up */
{
	int pid;

	vttidy();
	pid = getpid();
	kill(pid,SIGTSTP);
}

rtfrmshell()
{
	TTopen();
	curwp->w_flag = WFHARD;
	sgarbf = TRUE;
}
#endif
 7-Mar-88 16:40:27-PST,759;000000000000
Mail-From: KLH created at  7-Mar-88 15:47:11
Date: Mon, 7 Mar 88 15:44:00 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: TERMCAP problem with tgetnum
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

OK, that nailed it down.  The GNU coder took a lot of liberties with
(char *) to (int) conversions and assumed it was OK to pretend that
getenv() returned an (int), which it doesn't -- it returns a (char *)
and must be declared as such.  Sigh.

Fixed in the canonical source here; in your copy of TRMCAP.C you can
fix it by inserting the top-level declaration "extern char *getenv();"
at the beginning.
-------
 8-Mar-88 22:27:07-PST,999;000000000000
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Tue 8 Mar 88 22:21:44-PST
Date: Tue, 8 Mar 1988  23:21 MST
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: Strange bug

I'm *still* trying to get compress to work, and just found one reason
it hasn't.  The following is the reduced extract to demonstrate the
problem.  Compile and run normally to see the problem.  Compile again
with -DTEST and run to see the correct display.

--Frank

--------------------
#include <stdlib.h>

#  define BITS	16
#define INIT_BITS 9			/* initial number of bits/code */
int maxbits = BITS;			/* user settable max # bits/code */

main()
{
    printf("maxbits = %d\n", maxbits);
    if(maxbits < INIT_BITS) maxbits = INIT_BITS;
#ifdef TEST
    printf("maxbits = %d\n", maxbits);
#endif
    if (maxbits > BITS) maxbits = BITS;
    printf("maxbits = %d\n", maxbits);
}
 9-Mar-88 12:07:26-PST,793;000000000000
Mail-From: KLH created at  9-Mar-88 11:59:41
Date: Wed, 9 Mar 88 11:59:14 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Strange bug
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Thanks to your small test case I was able to quickly track down and fix
the problem, which was Yet Another Optimizer Bug.  (It was removing what
it thought was a superfluous MOVEM without checking to see whether it
was skipped or not.)

The new version won't be available until I finish some more tests since
it incorporates fixes to several other bugs that have piled up over the
past couple of months.  I expect to release it in a day or two, however.
-------
11-Mar-88 12:15:07-PST,3279;000000000010
Received: from SCIENCE.UTAH.EDU by SRI-NIC.ARPA with TCP; Fri 11 Mar 88 12:05:01-PST
Date: Fri 11 Mar 88 11:42:37-MST
From: "Nelson H.F. Beebe" <[email protected]>
Subject: Problem in fstat()/stat()
To: [email protected]
cc: [email protected]
X-US-Mail: "Center for Scientific Computing, South Physics, University of Utah, Salt Lake City, UT 84112"
X-Telephone: (801) 581-5254
Message-ID: <[email protected]>

Under Unix, fstat() on a new open file correctly returns the
file size after an fflush(); I ran the following test
program on VAX 4.3BSD, Sun OS 3.3 (4.2BSD), Gould 4.2BSD,
Iris (System V), and HPUX (System V), and on all got the
output

fstat: statbuf.st_size = 1029 (expected 1029)
stat: statbuf.st_size = 1029 (expected 1029)

Here is a PHOTO log for our current version of KCC.  As you
can see from the output, PCC-20 and VAX VMS are also
incorrect.  I'm not worried about the different non-zero
byte counts, because that reflects end-of-line translation.
However, the fact that fstat() returns a 0 file size when
the file is not empty broke a program I tried to install
this morning.


[PHOTO:  Recording initiated  Fri 11-Mar-88 11:29AM]

 TOPS-20 Command processor 5(712)
@type bug.c
------------------
APS:<BEEBE>BUG.C.5
------------------

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>

#define MAXSIZE 1029			/* this number is ARBITRARY */

struct stat statbuf;

main()
{
    int k;
    static char fname[] = "bug.tmp";
    FILE* fp;
    
    fp = fopen(fname,"w");
    if (fp == (FILE*)NULL)
    {
        fprintf(stderr,"?Cannot open %s\n",fname);
	exit(1);
    }

    for (k = 0; k < MAXSIZE; ++k)	/* write the file */
       putc(k,fp);

    fflush(fp);				/* empty buffers */

    if (fstat(fileno(fp),&statbuf))	/* get its size */
	perror(fname);
    else
        fprintf(stderr,"fstat: statbuf.st_size = %d (expected %d)\n",
	    statbuf.st_size,MAXSIZE);

    fclose(fp);
    if (stat(fname,&statbuf))		/* get its size again */
	perror(fname);
    else
        fprintf(stderr,"stat: statbuf.st_size = %d (expected %d)\n",
	    statbuf.st_size,MAXSIZE);
}
@
@def c: cnew:
@v cnew:kcc.exe.0,cnew:libc.rel.0

   ND20:<SUBSYS.KCC.NEW>
 KCC.EXE.583;P777752      156 79872(36)  13-Jan-88 05:44:47 KLH       
 LIBC.REL.206;P777752      84 42858(36)  16-Dec-87 23:27:22 KLH       

 Total of 240 pages in 2 files
@kcc -o bug bug.c
KCC:	bug
<BEEBE>BUG.PRE.1
<BEEBE>BUG.FAI.1
FAIL:  bug
LINK:	Loading
@bug
fstat: statbuf.st_size = 0 (expected 1029)
stat: statbuf.st_size = 1031 (expected 1029)
@bug
fstat: statbuf.st_size = 0 (expected 1029)
stat: statbuf.st_size = 1031 (expected 1029)
@del bug.rel,bug.exe,bug.tmp
 BUG.REL.4 [OK]
 BUG.EXE.4 [OK]
 BUG.TMP.6 [OK]
@cc -o bug bug.c
[PCC: bug.c]
MACRO:	bug.c
LINK:	Loading
@bug
fstat: statbuf.st_size = 0 (expected 1029)
stat: statbuf.st_size = 1030 (expected 1029)
@
@; Here is what VAX VMS (VMS C 2.3 + 2.2 libraries) says:
@remark
Type remark.  End with CTRL/Z.
NHFB-8600>run bug
fstat: statbuf.st_size = 0 (expected 1029)
stat: statbuf.st_size = 1029 (expected 1029)
^Z
@pop

[PHOTO:  Recording terminated  Fri 11-Mar-88 11:37AM]
-------
12-Mar-88 00:15:49-PST,520;000000000000
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sat 12 Mar 88 00:13:17-PST
Date: Sat, 12 Mar 1988  01:13 MST
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: C:ASSERT.H is broken

The definition has a comma instead of a space before abort() and an
extra or misplaced 0 following it.  Also, the test does not otherwise
compile properly - it should be an if(!(e)) with braces...

--Frank
14-Mar-88 14:47:06-PST,823;000000000000
Mail-From: KLH created at 14-Mar-88 14:44:50
Date: Mon, 14 Mar 88 14:44:45 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: C:ASSERT.H is broken
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

The version I had (assert.h.2) did compile properly.  Perhaps you were
being misled by the warning (not error) message about a discarded operator.
I re-checked ANSI to verify that the macro is correct (H&S is a bit
different -- it implies that "assert" is a statement, whereas ANSI implies
it is an expression (though without a value)).

I added a couple of (void) casts to ensure that it conformed to ANSI's
specification that it have no value, and to shut up the warning.
-------
18-Mar-88 00:33:49-PST,1006;000000000000
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Fri 18 Mar 88 00:30:30-PST
Date: Fri, 18 Mar 1988  01:07 MST
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: Bug in strtok()

Given a string with more than one delimiter, e.g., two TAB characters,
between a pair of tokens, strtok() fails to return the second token.

My reference says:  "Strok considers the string s1 to consist of a
sequence of zero or more text tokens separated by spans of one or more
characters from the string s2."

Example:

#include <stdio.h>

char	*strtok();

main()
{
	char	*cmd;
	char	*tok;

	cmd = strtok("cmd	tok", "\t\r\n");  /* one TAB case */
	tok = strtok((char *)NULL, "\t\r\n");
	printf ("cmd: :%s:\ntok: :%s:\n", cmd, tok);
	cmd = strtok("cmd		tok", "\t\r\n"); /* two TAB case */
	tok = strtok((char *)NULL, "\t\r\n");
	printf ("cmd: :%s:\ntok: :%s:\n", cmd, tok);
}
18-Mar-88 23:34:01-PST,384;000000000000
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Fri 18 Mar 88 23:26:51-PST
Date: Sat, 19 Mar 1988  00:24 MST
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: ttyname() and isatty()

Are the subject functions scheduled for implementation soon?

--Frank
21-Mar-88 12:30:36-PST,438;000000000000
Mail-From: KLH created at 21-Mar-88 12:30:02
Date: Mon, 21 Mar 88 12:29:58 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: ttyname() and isatty()
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Well, they weren't scheduled, but they should be quite simple, so
I'll add them to the list.
-------
21-Mar-88 12:50:39-PST,1234;000000000000
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Mon 21 Mar 88 12:48:22-PST
Date: Mon, 21 Mar 1988  13:48 MST
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   Ken Harrenstien <[email protected]>
Cc:   [email protected], [email protected]
Subject: ttyname() and isatty()
In-reply-to: Msg of 21 Mar 1988  13:29-MST from Ken Harrenstien <KLH at SRI-NIC.ARPA>

Ken,

Thanks.  ttyname() is the C thing to use when generating log filenames
for uucp when more than one may be active.  Generally speaking,
neither ttyname() nor isatty() is used to find out about some tty
other than the one currently used by the program calling the function.
However, that is not always the case, especially for certain utility
programs.  Otherwise, it would be a simple matter to use GJINF%.

The question remains as to what isatty() should return when the
program is running in a batch job.  It is not clear to me that there
is an equivalent concept for batch jobs in Unix.  Is the distinction
implied by a 0 return from isatty() that the job is not interactive,
meaning in the background, which is not quite the same as batch mode
in the TOPS20 sense?

--Frank
21-Mar-88 13:00:36-PST,1194;000000000000
Mail-From: KLH created at 21-Mar-88 12:56:12
Date: Mon, 21 Mar 88 12:56:04 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: ttyname() and isatty()
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Well, it all depends on what FD you give to those functions.  "isatty()"
is primarily used to determine whether I/O on a particular FD is being
redirected to a file or not.  Unix does have the concept of running in
the background, but TTY I/O still takes place (or can be blocked, depending
on what version of Unix you're using).  For a batch job on TOPS-20 I
think isatty() on an otherwise un-redirected FD will return TRUE -- that is,
i/o is happening to a PTY which is just a software TTY.  And I think that's
what you want to happen.

I sure wish Unix had the equivalent of JFNS% (ie a generic ttyname()).  The
design of the file system has given the false impression that this is
impossible, but the kernel could easily remember the filename that a FD was
opened with, and return that.  Oh, and version numbers.  Arrrrrggggghhhh....
-------
21-Mar-88 13:25:44-PST,2369;000000000000
Mail-From: IAN created at 21-Mar-88 13:22:07
Date: Mon, 21 Mar 88 13:21:56 PST
From: Ian Macky <[email protected]>
Subject: Re: Bug in strtok()
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

You seem to be correct about strtok().  The description in KCC says "The
function strtok(str, set) is used to separate a string /str/ into tokens
separated by characters from the string /set/."

The explicit detailed description which follows doesn't allow"characters",
tho.  I take this to be an oversight, since it's obvious that multiple
delimiters should be allowed.

Here's a comparison of the old code vs. the new, fixed code:

;COMPARISON OF PS:<C.LIB>STRING.C.38 AND PS:<C.LIB>STRING.C.39
;OPTIONS ARE    /3

**** FILE PS:<C.LIB>STRING.C.38, 7-31 (7716)
    char *p, *old_tokptr;
    if (str) {				/* if given a new string: point to */
	p = str + strspn(str, set);	/* first char of str not in set. */
	if (!*p)			/* if all characters were in set, */
	    return _tokptr = NULL;	/* return NULL pointer. */
	_tokptr = p;			/* else start tokenizing here. */
    } else if (!_tokptr)		/* no target string or internal */
	return NULL;			/* state, so what can we do? */
    old_tokptr = _tokptr;		/* save original _tokptr */
    if (p = strpbrk(_tokptr, set)) {	/* if found a character from set */
	*p = '\0';			/* clobber that character */
	_tokptr = ++p;			/* point to after that char */
    } else
	_tokptr = NULL;			/* no character found, so done. */
    return old_tokptr;			/* return original pointer */
**** FILE PS:<C.LIB>STRING.C.39, 7-31 (7716)
    char *source, *p, *start;
    source = (str) ? str : _tokptr;	/* new string or next part of old */
    p = source + strspn(source, set);	/* skip leading chars in set */
    if (!p || !*p)			/* nothing but separators? */
	return _tokptr = NULL;		/* fraid so, so done with string */
    start = p;				/* save start of token */
    if (p = strpbrk(start, set)) {	/* look for end of token now */
	*p = '\0';			/* found it, clobber terminator */
	_tokptr = ++p;			/* and point to after that char */
    } else				/* hit end of string, so no more */
	_tokptr = NULL;			/* next time. */
    return start;			/* return start of token */
***************

--ian
-------
29-Mar-88 06:57:29-PST,926;000000000000
Received: from TOPS20.DEC.COM by SRI-NIC.ARPA with TCP; Tue 29 Mar 88 06:52:54-PST
Date: 29 Mar 1988 0952-EST
From: "Andy Puchrik" <[email protected]>
To: [email protected]
cc: [email protected]
DTN: "297-7157 (617-467-7157)"
Loc/MS: "MRO1-2/L14 (Pole M13)"
Subject: monsym_*.h
Message-ID: <"MS11(6040)+GLXLIB6(0)" 12386204325.22.321.32978 at TOPS20.DEC.COM>

To check out a recent new version of kcc I attempted to build Nelson Beebe's
make utility.  I'm missing the files monsym_[c,f,g,m,p,r,s].h (pardon the
unix syntax).  I've sent mail to Mr. Beebe at science.utah.edu and hope to
hear something eventually.  klh said to direct these questions to bug-kcc
and not info-kcc so here I am.

Are the monsym_*.h files part of the kcc compiler release?  Are they generated
like monsym.h from monsym.mac?  I didn't find them on sri-nic on either sys:
or c:.

Regards,
Andy Puchrik
   --------
29-Mar-88 11:04:14-PST,945;000000000000
Mail-From: KLH created at 29-Mar-88 10:59:54
Date: Tue, 29 Mar 88 10:58:22 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: monsym_*.h
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <"MS11(6040)+GLXLIB6(0)" 12386204325.22.321.32978 at TOPS20.DEC.COM>
Message-ID: <[email protected]>

Hi again.  I was hoping Nelson would have answered your question by now.
(If you haven't guessed, I answer BUG-KCC mail also, it's just that
the mailing list is much smaller and avoids cluttering mailboxes).  The
monsym_ files are generated at Utah and are not part of the KCC release.

Because they are so large, we are trying to figure out an alternative
way of getting at the monitor symbols; in the meantime it's necessary
to include the appropriate bag of bitdefs.  jsys.h as distributed with
KCC only defines the JSYSes plus the symbols that the runtime library
uses.
-------
29-Mar-88 23:37:55-PST,1120;000000000000
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Tue 29 Mar 88 23:36:39-PST
Date: Wed, 30 Mar 1988  02:35 EST
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   "Andy Puchrik" <[email protected]>
Cc:   [email protected]
Subject: monsym_*.h
In-reply-to: Msg of 29 Mar 1988  09:52-EST from "Andy Puchrik" <[email protected]>

Purely FYI, the CHIVES (MIT TOPS-20 domain resolver) distribution
includes a batch job and a couple of programs that will make a single,
monolithic file called MONSYM.H from your system's installed
MONSYM.UNV.  I provide this because some of the system bits that the
CHIVES system needs changed between rel5 and rel6 of TOPS-20, both of
which I have to support.

I agree with KLH that this is a godawful kludge.  MONSYM.H is so big
that KCC has to run in extended addressing in order to have enough
address space for it, and there is a noticable slowdown in compile
time when a file #include's it.

If you want this stuff, you can get it via ANONYMOUS FTP from
[XX.LCS.MIT.EDU]XX:<CHIVES.BETA.KCC>.

--Rob
 1-Apr-88 01:19:33-PST,645;000000000000
Received: from CU20B.COLUMBIA.EDU by SRI-NIC.ARPA with TCP; Fri 1 Apr 88 01:17:22-PST
Date: Fri 1 Apr 88 04:16:26-EST
From: Ken Rossman <[email protected]>
Subject: FD <-> JFN, fcntl
To: [email protected]
Address: 715 Watson Labs, 612 W. 115th St, NY NY 10025
Phone: (212) 280-4876
Message-ID: <[email protected]>

I seem to be having some trouble switching between KCC FDs and TOPS JFNs.

I call fcntl() like so:

     fd = fcntl(jfn,F_SETSYSFD,0);

Is this the correct calling procedure?  I am getting -1 back.  The JFN is
valid, as some jsys() calls on the same JFN work OK.  /Ken
-------
 1-Apr-88 01:54:31-PST,1635;000000000000
Mail-From: KLH created at  1-Apr-88 01:52:34
Date: Fri, 1 Apr 88 01:52:31 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: FD <-> JFN, fcntl
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Well, no, for two reasons.  The main one is that the F_SETSYSFD function
is not implemented yet (it may never be).  Second, if it were, it would
look like this:
		fd = fcntl(fd, F_SETSYSFD, jfn);
where the argument fd is either that of a valid fd (it is clobbered if already
open) or -1 to select an unused fd.  Anyway, I have added a comment
to <fcntl.h> flagging this as unimplemented, to prevent further confusion.

Now for the good news -- what IS implemented is the O_SYSFD flag.
This works with open() and is a much easier and more straightforward
business.  Here's the CURRENT usage:

		fd = open("", O_SYSFD+<other flags>, jfn);

Note that the jfn is furnished in place of the mode bits, which are
presently ignored on T20 anyway.  The jfn must NOT be already open; it
will be opened as specified by the other flags.

This hasn't yet been documented or announced as it is a quite recent
addition and I'm still considering changing the call so that it looks
like this instead:

		fd = open((char *)jfn, O_SYSFD+<flags>, mode);

In other words, the jfn (suitably cast to indicate something funny is going
on) replaces the pathname argument; this is logically more pleasing in spite
of the type clash.  If you (or anyone else) have an opinion let me know.

-------
 1-Apr-88 10:04:44-PST,2856;000000000000
Received: from CU20B.COLUMBIA.EDU by SRI-NIC.ARPA with TCP; Fri 1 Apr 88 10:03:13-PST
Date: Fri 1 Apr 88 13:01:44-EST
From: Ken Rossman <[email protected]>
Subject: Re: FD <-> JFN, fcntl
To: [email protected], [email protected]
Address: 715 Watson Labs, 612 W. 115th St, NY NY 10025
Phone: (212) 280-4876
Message-ID: <[email protected]>

OK, so F_SETSYSFD is not implemented and probably won't be (by the way, why
is this?  Is it too messy to do?)...

As for the method you outlined using the special JFN hack to the open()
call (since you asked if I had an opinion), I'm not real particular whether
the calling conventions are:

    fd = open("", O_SYSFD+<other flags>, jfn);

or:

    fd = open((char *)jfn, O_SYSFD+<flags>, mode);

I guess in the former case, you don't have this funny incompatible looking
casting, which appeears to be rather messy, but then you do have to use up
the mode field (who knows, you might want to use it for something someday).

As long as they both get the job done, I'm happy with either form.  I guess
I lean a little bit towards the format where you supply the JFN, cast to
type "char *" as the first arg...

What I'm trying to do, by the way, is a DECnet OPENF% call.  After I'm done
opening a DECnet connection (and that also means I have to sit in a loop
doing MTOPR%'s to check to see if the link got connected, just after I do
the OPENF%, whatever form that OPENF% takes), I need to have both a KCC FD
and a TOPS JFN.  The JFN, so I can perform various TOPSish operations via
the jsys() call, and the FD, of course, so I can perform I/O operations at
the KCC I/O level.

By the way, I'm assuming that the read() and write() calls eventually boil
down to SINR%'s and SOUTR%'s at some point.  This is critical to what I am
trying to do, but I haven't even gotten that far as yet.

I'm basically attempting to port some Ultrix C code that talks to DECnet
over to TOPS-20, writing my own versions of some of the the Ultrix DECnet
subroutines (dnet_conn(), dnet_eof()).  Perhaps I will write additional
subroutines which hide the JFN from the calling program entirely and
somehow internally associate a particular KCC FD with a JFN that only that
module knows about.  But then, of course, I don't always know when a KCC FD
has been swapped out from under me with another value by the calling
program, and might end up performing operations on either the wrong JFN or
an invalid one.

By the way, you said that F_SETSYSFD wasn't implemented.  But is
F_GETSYSFD implemented?  If so, maybe there's an easy way around this, in
that I could use KCC's open() call, get a KCC FD on the network connection,
and then get a JFN on that FD using fcntl() each time I need one.  That
way, it should always be the right value.  /Ken
-------
 1-Apr-88 11:49:48-PST,1813;000000000000
Mail-From: KLH created at  1-Apr-88 11:46:23
Date: Fri, 1 Apr 88 11:45:58 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: FD <-> JFN, fcntl
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

F_SETSYSFD isn't implemented because it's messy and I didn't have much
time.  There is also no obvious way with fcntl() to properly set up a
bunch of auxiliary options that are possible with open(), such as whether
to do newline conversion.  This could be done with further fcntl() commands
but the complexity seems excessive.

read() does SIN%.  It uses SIBE% to avoid hanging on "slow" devices,
so that as long as some input exists, it will be returned immediately;
hanging only happens when there is no input at all.  Supposedly, SINR%
has the potential for losing some data, whereas SIN% can read across
record boundaries.  If this is not true, things may become very
complicated.

write() uses either SOUT% or SOUTR%, depending on the device type.  For
.DVTCP it uses SOUTR%; everything else is SOUT%.  It is easy to add further
device types to the switch statement.  What's the .DV type number?

F_GETSYSFD is implemented.  You noted in a separate message that it returns
-1 for .PRIOU, .PRIIN, and .CTTRM.  What is happening is that the routines
derive the REAL jfn or device designator for .PRIOU and .PRIIN (this is
necessary for some things like redirection).  -1 happens to be .CTTRM.
If you are actually getting -1,,-1 instead of 0,,-1 then that is a bug.

We don't have DECNET so I can't guess why open() fails for decnet pathnames.
It could be any of a number of things.  You could look at open.c (it hasn't
changed that much).
-------
 1-Apr-88 11:59:46-PST,826;000000000000
Received: from CU20B.COLUMBIA.EDU by SRI-NIC.ARPA with TCP; Fri 1 Apr 88 11:56:14-PST
Date: Fri 1 Apr 88 14:38:20-EST
From: Ken Rossman <[email protected]>
Subject: Re: FD <-> JFN, fcntl
To: [email protected], [email protected]
Address: 715 Watson Labs, 612 W. 115th St, NY NY 10025
Phone: (212) 280-4876
Message-ID: <[email protected]>

Forget all that other stuff I sent before...

I've managed to get a DECnet connection open using KCC open(), and
combinations of fcntl(x,F_GETSYSFD,y) calls and jsys() calls.

Now, it would appear that it was a bad assumption to believe that
KCC read() and write() used SINR% and SOUTR%...  I supposed there
are plenty of cases where that would be bad.

So I'll work around this next.

Thanks for the info on fcntl().  /Ken
-------
 1-Apr-88 12:30:11-PST,4330;000000000000
Received: from CU20B.COLUMBIA.EDU by SRI-NIC.ARPA with TCP; Fri 1 Apr 88 12:23:43-PST
Date: Fri 1 Apr 88 15:22:36-EST
From: Ken Rossman <[email protected]>
Subject: Re: FD <-> JFN, fcntl
To: [email protected], [email protected]
Address: 715 Watson Labs, 612 W. 115th St, NY NY 10025
Phone: (212) 280-4876
Message-ID: <[email protected]>

Thanks for the speedy replies...

  F_SETSYSFD isn't implemented because it's messy and I didn't have much
  time.  There is also no obvious way with fcntl() to properly set up a
  bunch of auxiliary options that are possible with open()...

And as it turns out, most of the time you probably wouldn't need the
F_SETSYSFD function anyway, I'd think.  But the other other direction IS
quite useful.

  read() does SIN%.  It uses SIBE% to avoid hanging on "slow" devices, so
  that as long as some input exists, it will be returned immediately;
  hanging only happens when there is no input at all.  Supposedly, SINR%
  has the potential for losing some data, whereas SIN% can read across
  record boundaries.  If this is not true, things may become very complicated.

Yes, I believe this is true for the most part, though I've seen TOPS-20 do
some funny things with DECnet connections and SINR%/SOUTR%.  But that's
supposedly what you should use mostly to talk DECnet...

Even after having worked with TOPS DECnet for several years here now, I'm
STILL confused by some of its behavior.

  write() uses either SOUT% or SOUTR%, depending on the device type.  For
  .DVTCP it uses SOUTR%; everything else is SOUT%.

I don't see .DVTCP.  Do you mean .DVNET?

  It is easy to add further device types to the switch statement.  What's
  the .DV type number?

In MONSYM, the symbols for DECnet are .DVDCN (active/object connection),
and .DVSRV (passive/target) connection.

It would be helpful to have write() do a SOUTR% if the above device types
were in use, and it would also be helpful to have read() to a SINR%, though
I'm still not sure if this really is the right thing to do.

It won't work for what I'm doing the way it's implemented now, so I'll just
write jacket routines that do what I need to do.

  F_GETSYSFD is implemented.  You noted in a separate message that it
  returns -1 for .PRIOU, .PRIIN, and .CTTRM...  If you are actually getting
  -1,,-1 instead of 0,,-1 then that is a bug.

I am indeed getting an 18 bit -1 (which IS .CTTRM).  But I get that back
for ALL THREE stdio file designators.  Is this correct?  Are you saying
above that .PRIIN and .PRIOU actually end up translating to .CTTRM in this
particular case (i.e. if I haven't swapped my stdin/stdout designators in
the program somewhere)?  I guess that makes sense...

  We don't have DECNET so I can't guess why open() fails for decnet
  pathnames.

Sorry to bother you with that one.  The mistake was mine, and it was a
stupid one.  I made the silly assumtion (even though I remember now reading
material to the contrary in USYS) that if I used the O_BINARY option in the
open() call, I'd get an 8 bit connection, when in fact, it tries to open
the file in 9 bit mode.  So I fixed that one up already.

  It could be any of a number of things.  You could look at open.c (it
  hasn't changed that much).

I have no KCC source code here.  I don't even know where it is.

Anyway, I think I have a much better handle on what is going on now, and I
thank you for your patience in replying to all this.  I don't mean to be
bouncing my individual programming tasks off of you as a consultant.

I had just found as of late that I could get quite a bit further than I
used to think with much less mucking around with "pure" C code to make it
do system-dependent things under TOPS-20.  I've been having lots of fun
rewriting some existing TOPS tools I have here (stuff written in MACRO), as
well as porting things over from our Ultrix machine (this DECnet code), and
seeing just how far I could get without actually having to write a lot of
separate, hacky code to get down to the Jsys level as much (never mind
going into #asm code), and I'm very pleasantly surprised at just how far I
can get and still keep things "pure".  I think you guys have done an
excellent job on this compiler!  /Ken
-------
 4-Apr-88 14:20:25-PDT,5408;000000000000
Received: from SCIENCE.UTAH.EDU by SRI-NIC.ARPA with TCP; Mon 4 Apr 88 14:15:58-PDT
Date: Mon 4 Apr 88 15:16:07-MST
From: "Nelson H.F. Beebe" <[email protected]>
Subject: A new KCC compiler optimizer bug
To: [email protected]
cc: [email protected]
X-US-Mail: "Center for Scientific Computing, South Physics, University of Utah, Salt Lake City, UT 84112"
X-Telephone: (801) 581-5254
Message-ID: <[email protected]>

In the following program (a runnable fragment of a much
larger multi-O/S program, of which the code here is part of
that for TOPS-20), KCC  seems to lose the code for the
assignment

	a = (a == SNULL) ? p : a;

when the code is compiled by

	kcc -o bug2 bug2.c

Recompiling with optimization suppressed 

	kcc -O= -o bug2 bug2.c

produces CORRECT output:

a = 111100400201 p = 111100400201 (int)(p-a) = 0
a = 111100400201 p = 111100400201 (int)(p-a) = 0

so I at least have a workaround for now.

[PHOTO:  Recording initiated  Mon 4-Apr-88 3:03PM]

 TOPS-20 Command processor 5(712)
@v sys:kcc.exe

   PS:<SUBSYS.KCC>
 KCC.EXE.586;P777752      158 80896(36)   9-Mar-88 19:03:02 KLH       
@get sys:kcc.exe
@i vers
 College of Science DecSystem-20, TOPS-20 Monitor 6.1(7030)
 TOPS-20 Command processor 5(712)
 Program is KCC
@
@type bug2.c
--------------------------
APS:<BEEBE.MYMAKE>BUG2.C.2
--------------------------

#include <stdio.h>

#include <string.h>

#define MIN(a,b) (((a) < (b)) ? (a) : (b))

#define FULLNAME "node::file.ext"
#define SNULL	((char*)NULL)
#define NUL_CHAR '\0'

#define CHARS(n) (2*(n)+1) /* allow for Ctl-V quoting, plus trailing NUL */
#define CTLV ('V' & 037)
#define MAX_NOD	CHARS(6+2)
#define MAX_DEV	CHARS(6+1)
#define MAX_DIR	CHARS(1+39+1)
#define MAX_NAM	CHARS(39)
#define MAX_EXT	CHARS(39)
#define MAX_GEN	CHARS(1+6)
#define MAX_MOD CHARS(1+MAX_NAM+MAX_EXT+1)	/* "(name.ext)" */
#define MAX_ATR CHARS(256)	/* uncertain, but large enough */

main()
{
	static char node[MAX_NOD];
	static char device[MAX_DEV];
	static char directory[MAX_DIR];
	static char name[MAX_NAM];
	static char extension[MAX_EXT];
	static char generation[MAX_GEN];
	static char module[MAX_MOD];
	static char attributes[MAX_ATR];
	char* p;		/* pointer to start of current field */
	char* q;		/* pointer to start of next field */
	char* r;		/* pointer to start of next field */
	char* m;		/* pointer to start of "(module)" */
	char* a;		/* pointer to start of ";attributes" */
	int length;		/* length of current field */

	/* collect ";attributes" */
	a = strrchr(FULLNAME,';');
	p = strrchr(FULLNAME,NUL_CHAR);
	a = (a == SNULL) ? p : a;
	length = (int)(p-a);
	printf("a = %09o p = %09o (int)(p-a) = %d\n",a,p,length);
	length = MIN(MAX_ATR-1,length);
	printf("a = %09o p = %09o (int)(p-a) = %d\n",a,p,length);
}
[K@
@bug2
a = 000000000 p = 111100400101 (int)(p-a) = 604504323
a = 000000000 p = 111100400101 (int)(p-a) = 512
@
@type bug2.fai
----------------------------
APS:<BEEBE.MYMAKE>BUG2.FAI.1
----------------------------

	TITLE	bug2
	.REQUEST C:LIBc.REL
	$$CVER==<2,,2>
	INTERN $$CVER
	OPDEF ADJBP [IBP]
DEFINE %CHRBP(A,M)
<	SETO A,
	ADJBP A,M
>
IFNDEF ERJMP,< OPDEF ERJMP [JUMP 16,] >
OPDEF ERJMPA [ERJMP]
OPDEF	XMOVEI	[SETMI]
	DEFINE IFIW <SETZ >
OPDEF XBLT [020000,,0]
	TWOSEG	400000	
	RELOC	0	
	RELOC	400000	
	DEFINE %%CODE <RELOC>
	DEFINE %%DATA <RELOC>
PURGE IFE,IFN,IFG,IFGE,IFL,IFLE,IFDEF,IFNDEF,IFIDN,IFDIF

	%%DATA
$1:	BLOCK	5
$2:	BLOCK	4
$3:	BLOCK	25
$4:	BLOCK	24
$5:	BLOCK	24
$6:	BLOCK	4
$7:	BLOCK	121
$8:	BLOCK	201

	%%CODE
main:
	ADJSP 17,6
	PUSH 17,[73]
	PUSH 17,[$$BP90+$$SECT,,$9]
	PUSHJ 17,strrch
	MOVEM 1,-3(17)
	SETZB 16,-1(17)
	ADJSP 17,-1
	PUSH 17,[$$BP90+$$SECT,,$10]
	PUSHJ 17,strrch

; where is the code here for "	a = (a == SNULL) ? p : a"?

	MOVEM 1,-7(17)
	MOVE 6,1
	LDB 16,[$$BPSZ,,6]
	SUB 6,-3(17)
	MUL 6,$BPMUL(16)
	ASH 7,-$$BSHF
	ADD 6,$BPADT(16)
	ADD 7,(6)
	MOVEM 7,-2(17)
	MOVEM 7,-1(17)
	ADJSP 17,-1
	PUSH 17,-6(17)
	PUSH 17,-3(17)
	PUSH 17,[$$BP90+$$SECT,,$13]
	PUSHJ 17,printf
	MOVEI 5,1000
	CAML 5,-4(17)
	 MOVE 5,-4(17)
	MOVEM 5,-4(17)
	MOVEM 5,-3(17)
	ADJSP 17,-3
	PUSH 17,-6(17)
	PUSH 17,-3(17)
	PUSH 17,[$$BP90+$$SECT,,$16]
	PUSHJ 17,printf
	ADJSP 17,-12
	POPJ 17,
$16==.
	BYTE	(9) 141,40,75,40
	BYTE	(9) 45,60,71,157
	BYTE	(9) 40,160,40,75
	BYTE	(9) 40,45,60,71
	BYTE	(9) 157,40,50,151
	BYTE	(9) 156,164,51,50
	BYTE	(9) 160,55,141,51
	BYTE	(9) 40,75,40,45
	BYTE	(9) 144,12,0
	

$13==.
	BYTE	(9) 141,40,75,40
	BYTE	(9) 45,60,71,157
	BYTE	(9) 40,160,40,75
	BYTE	(9) 40,45,60,71
	BYTE	(9) 157,40,50,151
	BYTE	(9) 156,164,51,50
	BYTE	(9) 160,55,141,51
	BYTE	(9) 40,75,40,45
	BYTE	(9) 144,12,0
	

$10==.
	BYTE	(9) 156,157,144,145
	BYTE	(9) 72,72,146,151
	BYTE	(9) 154,145,56,145
	BYTE	(9) 170,164,0
	

$9==.
	BYTE	(9) 156,157,144,145
	BYTE	(9) 72,72,146,151
	BYTE	(9) 154,145,56,145
	BYTE	(9) 170,164,0
	


$$CPKI==0
	INTERN $$CPKI
$$CPKA==0
	INTERN $$CPKA

	LIT
$$STRT: JRST $START
	JRST $START+1
	EXTERN	$BPADT
	EXTERN	$BPMUL
	EXTERN	$START
	EXTERN	$$BSHF
	EXTERN	$$BPSZ
	EXTERN	$$BP90
	EXTERN	$$SECT
	EXTERN	$$$CPU
	EXTERN	$$$CRT
	EXTERN	printf
	EXTERN	strrch
	INTERN	main
	END <2,,$$STRT>
@pop

[PHOTO:  Recording terminated  Mon 4-Apr-88 3:05PM]
-------
 4-Apr-88 19:10:32-PDT,2570;000000000000
Mail-From: KLH created at  4-Apr-88 19:07:31
Date: Mon, 4 Apr 88 19:07:27 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: A new KCC compiler optimizer bug
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

This one is real hard.  I understand now why it is happening, but the fix
I tested resulted in losing some very nice optimizations when I tried it
out on other code.  The problem is I haven't yet figured out how to
tell the optimizer that what it is doing is wrong, because by the time it
gets to the decision point, both the good and bad cases look just the same,
and the hell of it is that each step SEEMS so reasonable... and 99.99% of
the time it's fine.

What happens is that the code initially looks something like this:

	...	; call to function (strrchr), leaves result in 1
	MOVEM 1,PP
	SKIPE 3,A
	 JRST $1
	MOVE 4,PP
	MOVE 1,4
	JRST $2
$1:	...

When the MOVE 1,4 is added (by the ternary operator, which wants both results
left in the return ACs), it is optimized into:
	...
	SKIPE 3,A
	 JRST $1
	JRST $2
$1:

because it sees that AC1 already has the value of PP.  When the label $1
is about to be emitted, this is further optimized (to eliminate the label)
so that we have:
	...
	SKIPN 3,A
	 JRST $2

And now it generates the rest of the code, which starts out as:
	...
	SKIPN 3,A
	 JRST $2
	MOVE 4,A
	MOVE 1,4
$2:

But when the MOVE 4,A is added, it actually just changes the SKIPN 3,A
to a SKIPN 4,A.  So there's now:
	...
	SKIPN 4,A
	 JRST $2
	MOVE 1,4
$2:

And now, (the fatal part) the optimizer does the same thing it just did, by
flushing the MOVE 1,4 in favor of changing the SKIPN:
	...
	SKIPN 1,A
	 JRST $2
$2:

not realizing that this smashes the value of 1 which the other branch
wanted to preserve -- because there are no references to 1 anywhere up
to that point, and the previous instruction before the SKIPN is a
MOVEM 1, so it assumes the value in AC1 is no longer needed.  Things
then go away completely as the optimizer realizes that the resulting
code does nothing whatsoever.

Obviously there are some buggy assumptions here.  I "fixed" it by
forcing changereg() to never twiddle with AC1 across a JRST, but it
would be better to fix the way the ternary code is generated (AC1 and
AC2 are special frobs).  If I can't figure out something better in the
next day or so I'll give it up as a bad job and install the fix.
-------
 8-Apr-88 05:35:28-PDT,1275;000000000000
Mail-From: KLH created at  8-Apr-88 05:32:42
Date: Fri, 8 Apr 88 05:32:39 PDT
From: Ken Harrenstien <[email protected]>
Subject: Fixed KCC available
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

OK, after much pain and suffering I have installed a new KCC which fixes
the previously mentioned optimization problem, as well as a couple of
other things that turned up.  SYS:CC.EXE and SYS:CCX.EXE on SRI-NIC.

This binary includes some changes to the error reporting code that I
was testing at the time.  You will notice that error messages now have
a different format, which is more compact and I hope more informative.
It is intentionally similar to the style of Un*x compiler error
messages, with an extra line of context information.

As a minor fix, the maximum number of parse tree nodes is no longer a
fixed limit; more will be dynamically allocated as needed.

At Nelson's request, __COMPILER_KCC__ is now predefined.  I didn't
know what to define it to; on a whim I made it a string literal
containing KCC version information.  This may change if convention
seems to dictate a numerical value would be better.
-------
11-Apr-88 17:02:37-PDT,1121;000000000000
Mail-From: KLH created at 11-Apr-88 16:56:56
Date: Mon, 11 Apr 88 16:56:49 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Problem in fstat()/stat()
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

I just looked into this.  The problem is that on TOPS-20, a newly created
file does not exist until it has been closed, to the extent that when you
do a GTFDB% on the JFN you've been writing to, both .FBBYV and .FBSIZ are
always zero!  Barf, choke, puke.

It is possible for fstat() to determine that something like this is happening
(by looking for FB%NEX and FB%WNC in .FBCTL) but there is NO WAY it can find
the size information from the system itself; it would have to provide its
own guess from the variables within the USYS routines.  If the user has
been fiddling with the lseek I/O pointer then this guess will probably
be wrong, too.

The question is, is this worthwhile?  Or should we simply continue to
pass on the fact that T20 is losing horribly?
-------
11-Apr-88 18:51:11-PDT,601;000000000000
Mail-From: KLH created at 11-Apr-88 18:50:10
Date: Mon, 11 Apr 88 18:50:08 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Revised Last Write algorithm for mtime
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

As you requested, st_mtime is now always .FBWRT.  The current stat()
in the latest LIBC.REL now has the following invariant mappings:

	st_atime == .FBREF
	st_mtime == .FBWRT
	st_ctime == .FBCRE

(This is also documented in USYS.DOC)
-------
11-Apr-88 19:06:15-PDT,1033;000000000001
Received: from SCIENCE.UTAH.EDU by SRI-NIC.ARPA with TCP; Mon 11 Apr 88 19:02:52-PDT
Date: Mon 11 Apr 88 20:02:48-MST
From: "Nelson H.F. Beebe" <[email protected]>
Subject: Re: Problem in fstat()/stat()
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
X-US-Mail: "Center for Scientific Computing, South Physics, University of Utah, Salt Lake City, UT 84112"
X-Telephone: (801) 581-5254
Message-ID: <[email protected]>


Re: fstat()/stat() on TOPS-20 for new files

Although this was directed at someone else, I'd like to
comment.  I think the solution is to force a CHFDB call when
fstat()/stat() are called; that should force TOPS-20 to
update the file system, without it being necessary to close
the file.  The only oddity we've noted with CHFDB is that
you can end up with negative space used from INFO DISK;
apparently there is an inconsistency in the 5.x and 6.1
Monitors that affects this EXEC command.
-------
11-Apr-88 19:16:14-PDT,841;000000000001
Mail-From: KLH created at 11-Apr-88 19:12:49
Date: Mon, 11 Apr 88 19:12:46 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Problem in fstat()/stat()
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

I'm not quite sure what is meant by forcing a CHFDB%.  I have determined
that a no-op CHFDB% doesn't do anything, and I don't see any point in
setting .FBBYV and .FBSIZ by hand since that is what we are trying to
ask the system about!

I can make fstat() do something when it discovers that it is dealing with
a file of this sort, but I still don't know what this something should be.
If you know of a way to kick the monitor into doing what it should be
doing, please give details...
-------
12-Apr-88 02:21:15-PDT,902;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Tue 12 Apr 88 02:20:42-PDT
Date: Tue 12 Apr 88 05:19:33-EDT
From: Rob Austein <[email protected]>
Subject: Re: Problem in fstat()/stat()
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

See documentation for RFPTR% and RFBSZ%.  I think you can handle the byte
count by taking the max of (what RFPTR% returns) and (what you get from
examining the USYS variables), yes?

Having the file and its FDB not appear on disk until you do a CLOSF%
(or a UFPGS%) is a feature.  Letting you examine the FDB of a file
that's not on disk yet is a feature.  But it would help if they got
the code right; it's got all the info you need, it's just too stupid
to present it correctly when you ask for the FDB.

--Rob
-------
12-Apr-88 13:56:36-PDT,724;000000000001
Mail-From: KLH created at 12-Apr-88 13:53:14
Date: Tue, 12 Apr 88 13:52:03 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Problem in fstat()/stat()
To: [email protected]
cc: [email protected], [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

For your info, empirical testing has revealed that UFPGS% does nothing
about updating the FDB of the kind of file we are talking about; still
get zeros for .FBYYV and .FBSIZ.  RFPTR% and RFBSZ% do work and I guess
I'll try to cobble something together from those.   Geez, I never thought
I'd find a place where Unix did the right thing and TOPS-20 didn't.
-------
13-Apr-88 02:18:07-PDT,2198;000000000001
Received: from ifi.uio.no by SRI-NIC.ARPA with TCP; Wed 13 Apr 88 02:17:25-PDT
Received: from TONE by verdande.UIO.NO; Wed, 13 Apr 88 11:17:59 -0200
Date: Wed 13 Apr 88 11:17:12
From: Rein Tollevik <ID.IFI.TOLLEVIK-REIN%[email protected]>
Subject: KCC bug from ugly C coding
Sender: ID.IFI.TOLLEVIK-REIN@TONE
To: [email protected]
Reply-To: [email protected]
Message-Id: <12390075452.32.ID.IFI.TOLLEVIK-REIN@TONE>

I have discovered a bug in KCC when you use a conditional expression as
a statement.  I don't know whether it is the code generator or the
optimizer that makes the bug.  The bug doesn't do any harm if you don't
use both code and object optimizing, but the code don't look quite
right.  I can't see the use of the CAIN 0 instruction, it should never
do anything.  (Yes, I know I deserve to get wrong code when I write like
this, I discovered it when we was writing some code for the obfuscated C
code contest...  The program has broken most all other C compilers we
have tried it on in some or another part..)  Sorry, I don't have the KCC
version, but it was picked from src-nic 30. or 31. of March.

int a, b, c;
main() { a && (b = c); }

Generated code
with full optimizing:			Only parse and object optimizing:

main:	SKIPN 4,a		main:	SKIPN 4,a
	 JRST $2			 JRST $2
	MOVE 5,c			MOVE 5,c
	MOVEM 5,b			MOVEM 5,b
	CAIN 0				CAIE 0
$2==.	 TDZA 3,3			 SKIPA 3,[1]
	POPJ 17,		$2==.	 SETZ 3,
					POPJ 17,

By the way, is there any change to pick up source for the latest KCC
version the nearest days?  If I could pick up source for sys:cc.exe and
c:libc.rel I would be very pleased.  Our National Telephone Company have
decided to turn the antennae that we use for the satelite communication
to the Arpanet, so we lose our net connection the 15. of April.  They
was so kind to give us a hole week's notice...  I don't know when, or
if, we may find any other paths to the Arpanet.  We are so lucky to have
our local disks called A:, B: and C:, so I have to change the include
path from C: to KCC:

Rein Tollevik			email: [email protected]
Institute of Informatics	       (at least the nearest two days..)
University in Oslo
Norway

-------
13-Apr-88 03:58:06-PDT,490;000000000001
Mail-From: KLH created at 13-Apr-88 03:57:13
Date: Wed, 13 Apr 88 03:57:09 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: KCC bug from ugly C coding
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <12390075452.32.ID.IFI.TOLLEVIK-REIN@TONE>
Message-ID: <[email protected]>

Thanks for the bug report, I have fixed it and installed a new binary in
SYS:CC.EXE.  I'll send you a separate message later about the sources.
-------
13-Apr-88 19:18:39-PDT,1838;000000000001
Mail-From: KLH created at 13-Apr-88 19:18:32
Date: Wed, 13 Apr 88 19:18:24 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Problem in fstat()/stat()
To: [email protected]
cc: [email protected], [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

The TOPS-20/TENEX lossage of "ghost" files is causing yet another
problem with respect to the C library routines.  This surfaced when
I discovered how amazingly hard it was to get tmpfile() to work right,
and realized that almost every C program is making an assumption which is
not true on TOPS-20.

When a fopen() is done that creates a new file, a Un*x-type program
quite reasonably assumes that this file is now visible not only to the
outside world but also to itself.  The fact that it is NOT visible
until CLOSF%'d has several side effects other than the inability to
get at FDB information.  Most seriously, access() and stat() think
that no file of that name exists, and consequently things like
mktemp(), tmpnam(), and tmpfile() have no way of being sure that the
filename they generate is in fact unique.  The programs get a JFN for
what they think is a new version, and are surprised when attempting to
open them gives an "invalid simultaneous access" error.  This has affected
other software in the past, and is an exceedingly raw sore spot.

Since there is no hope of fixing this TOPS-20 brain damage (I'll never
buy it as a "feature"!), should the C library attempt to get around
all of these problems by having open() CLOSF% new disk files as soon
as they are OPENF%'d, hanging on to the JFN and re-opening it?
Despite the additional overhead, this idea is quite appealing to me;
if there are no counter-arguments I will probably do it.
-------
13-Apr-88 19:33:39-PDT,1119;000000000001
Received: from SCIENCE.UTAH.EDU by SRI-NIC.ARPA with TCP; Wed 13 Apr 88 19:32:00-PDT
Date: Wed 13 Apr 88 20:31:36-MST
From: "Nelson H.F. Beebe" <[email protected]>
Subject: Re: Problem in fstat()/stat()
To: [email protected], [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
X-US-Mail: "Center for Scientific Computing, South Physics, University of Utah, Salt Lake City, UT 84112"
X-Telephone: (801) 581-5254
Message-ID: <[email protected]>

I'll support an open/close/open sequence to solve the
problem; too bad there is no way for a user program (on
pretty much any operating system) to say, "this is an atomic
operation--don't do anything else until you've completed
it".  As it is, there is still the possibility of another
job getting in there between the first open/close pair and
hit the "invalid simultaneous access" situation.

Note that Unix used not to have a real rename-file system
call, until people discovered that it too is an operation
like open and close that needs to be atomic.
-------
13-Apr-88 23:22:33-PDT,1236;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Wed 13 Apr 88 23:21:58-PDT
Date: Thu 14 Apr 88 02:20:09-EDT
From: Rob Austein <[email protected]>
Subject: Re: Problem in fstat()/stat()
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Well, given that what I'd really like is a system with (a) GTJFN% with
an optional "atomic lock" flag and (b) RENMWO, I won't argue about
Twenex being braindamaged.  Although I do think that it compares
favorably with what I have to do in order to FTP zone files to a Unix
machine without having Zermatt.LCS.MIT.EDU disappear if the transfer
aborts (see XX:<HOSTS>HOST-DOMAIN.CTL if you want a laugh, it's too
vile to describe in polite company).

A sequence of OPENF%, UFPGS% would be slightly less prone to timing
screws than OPENF%, CLOSF%, OPENF%, but either of them would be
acceptable in a unix emulation package like the KCC USYS code.

I have this vague recollection that DEC did something similar to what
you propose as of FORTRAN v10 because some F77-required option to OPEN
got too hairy to implement if they didn't do it.

--Rob
-------
14-Apr-88 04:37:29-PDT,1005;000000000001
Mail-From: KLH created at 14-Apr-88 04:34:57
Date: Thu, 14 Apr 88 04:34:55 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Problem in fstat()/stat()
To: [email protected]
cc: [email protected], [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Sigh.  I tried the OPENF/CLOSF/OPENF gambit -- this does in fact cause
the file to exist, but the size and bytesize are 0 until the file has
been closf'd again after writing something.  The 0 size I might understand,
but not the 0 bytesize.  The real screw, though, is that fstat() is now
helpless -- it thinks the file exists, and so believes the FDB information
(which is 0) rather than trying to see whether RFPTR gives something else.
Back to where we started in the first place!

I suppose explict CHFDB%s could be done, but somehow I thought this was
the kind of thing the OS was supposed to take care of for you... silly me.
-------
21-Apr-88 12:46:13-PDT,1325;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Thu 21 Apr 88 12:43:45-PDT
Date: Thu, 21 Apr 1988  15:46 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
Subject: Making it easier to FTP KCC distributions

This is not a KCC bug per se, more of a request for something that
would make it a lot easier for those of us who use FTP to get KCC.

It is a real pain that the only indication we outsiders have of where
things go is the logical name KCCDIST:.  Given that TOPS-20 FTPSER
doesn't allow wildcard directory fields in directory listings, this
makes it somewhat painful to construct any kind of script that can
pull things over.

It would be nice if you provided, say a TAKE file for use with
Stanford TOPS-20 user FTP (assuming that TOPS-20 is the big KCC user
and that everybody who wants it can find a copy of Stanford FTP),
which had a bunch of lines like:

UPDATE dev:<KCC-n.mumble>*.*.* local-logical-name:*.*.*

You could use the same logical names for the local (non-NIC) side as
are used in the -DIRS-.CMD, so that all people would have to do is
customize that one file, retrieve your script, TAKE it, and go eat
dinner or something.

Just a suggestion, but one I hope you'll consider seriously.

--Rob
21-Apr-88 15:06:36-PDT,1227;000000000001
Mail-From: KLH created at 21-Apr-88 15:05:42
Date: Thu, 21 Apr 88 15:05:32 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Making it easier to FTP KCC distributions
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

That seems reasonable, but I don't know if TAKE will work -- that only
works with EXEC commands, doesn't it?  Also, I'm not sure if UPDATE is
the right FTP command to use -- there are two problems.  One is that
deleted files are left around and the other, more serious, is that
.REL files are out of synch -- UPDATE won't ensure that the newer file
is the one with the higher version number.

Nelson suggested something like this once, only it was (I think) a
simple listing of all files, put into a file with an 00 prefix.
Unfortunately I don't remember the exact details.  I'm trying not to
get sucked into more KCC hacking for a while, so I'm averse to
fiddling around myself, but if either of you can make a specific
proposal as to format I will install what you come up with.
(exception: I am not enthusiastic about one 00 file for each
directory.)
-------
22-Apr-88 09:12:16-PDT,3784;000000000001
Received: from SCIENCE.UTAH.EDU by SRI-NIC.ARPA with TCP; Fri 22 Apr 88 09:07:57-PDT
Date: Fri 22 Apr 88 10:08:18-MST
From: "Nelson H.F. Beebe" <[email protected]>
Subject: More comments on KCC-5 retrieval
To: [email protected]
cc: [email protected]
X-US-Mail: "Center for Scientific Computing, South Physics, University of Utah, Salt Lake City, UT 84112"
X-Telephone: (801) 581-5254
Message-ID: <[email protected]>

I too got zapped by FTP stupidity.  First I logged into
SRI-NIC and got the INSTAL.DOC  file, then edited it into a
script with lines like

Mult get <kcc-5.lib>*.*.* <*>*.*.*

With DUMPER, that does just what you expect: <*> becomes <kcc-5.lib>.
Alas, FTP dumped it into the same directory.

Next try:


Mult get <kcc-5.lib>*.*.* <kcc-5.lib>*.*.*

Same thing again -- everything in the top-level directory.

It seems with the SRI FTP, you have to connect to the local
directory first.  So the successful retrieval .MIC file
finally looked like this (feel free to steal it):

========================================================================
@enable
@ftp sri-nic.arpa
set opsys tops-20
set retain
set hash
set statistics


connect FES:<KCC-5>
continue
mult get <KCC-5>*.*.0

connect FES:<KCC-5.FAIL>
continue
mult get <KCC-5.FAIL>*.*.0

connect FES:<KCC-5.INCLUDE>
continue
mult get <KCC-5.INCLUDE>*.*.0

connect FES:<KCC-5.INCLUDE.SYS>
continue
mult get <KCC-5.INCLUDE.SYS>*.*.0

connect FES:<KCC-5.KCC>
continue
mult get <KCC-5.KCC>*.*.0

connect FES:<KCC-5.LIB>
continue
mult get <KCC-5.LIB>*.*.0

connect FES:<KCC-5.LIB.MATH>
continue
mult get <KCC-5.LIB.MATH>*.*.0

connect FES:<KCC-5.LIB.NETWORK>
continue
mult get <KCC-5.LIB.NETWORK>*.*.0

connect FES:<KCC-5.LIB.PML>
continue
mult get <KCC-5.LIB.PML>*.*.0

connect FES:<KCC-5.LIB.STDIO>
continue
mult get <KCC-5.LIB.STDIO>*.*.0

connect FES:<KCC-5.LIB.TEST>
continue
mult get <KCC-5.LIB.TEST>*.*.0

connect FES:<KCC-5.LIB.USYS>
continue
mult get <KCC-5.LIB.USYS>*.*.0
========================================================================

I use SRI FTP for large transfers in preference to SCORE FTP
because its data rate is about double (SET TRAP JSYS/ALL
shows it uses PMAP instead of SIN/SOUT).  Unfortunately, its
UPDATE command is broken--you cannot do MULTIPLE UPDATE, so
I revert to SCORE for that command.

With SRI FTP, a DIRECTORY command only gives filenames;
SCORE FTP will let you do 

DIRE *.*.0,
VERBOSE

to get the times as well.  At least between -20's, the
MULTIPLE UPDATE command solves the problem of getting just
the changes over.

If only DUMPER would write a saveset on disk, we could
eliminate all of these problems!  Unix tar would work for
source file distribution, but won't handle 36-bit byte files
(.REL, .EXE, et al), and loses author information, which,
along with time stamps, I consider critical for maintaining
up-to-date files on multiple machines.

To deal with the problem of providing directory listings to
folks who don't have SCORE FTP, for the Utah TeX
directories, I maintain 00TDIR.CMD and 00TDIR.LST files in
each directory (created by a .MIC file running TDIR and
SED).  The .CMD file can be used with most FTP's (you may
have to edit in an initial FTP command if your FTP lacks a
TAKE command -- e.g. Unix FTP).  Currently, I create these
manually with a DO command when I update the directories,
but they could easily be put in a nightly batch job.  At my
suggestion, Frank da Cruz added such a feature to the
Columbia Kermit distribution directories.

If there is interest in the 00TDIR scripts, I can provide
them on request; you do need to have Unix SED running
though.
-------
22-Apr-88 18:26:12-PDT,1309;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Fri 22 Apr 88 18:25:07-PDT
Date: Fri, 22 Apr 1988  19:23 MDT
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   "Nelson H.F. Beebe" <[email protected]>
Cc:   [email protected], [email protected]
Subject: More comments on KCC-5 retrieval
In-reply-to: Msg of 22 Apr 1988  11:08-MDT from Nelson H.F. Beebe <Beebe at SCIENCE.UTAH.EDU>

Nelson,

With the Stanford FTP, there is no problem.  If you have that, the
attacted batch ctl works correctly without the use of the
^C/CONNECT/CONTINUE sequences.

--Frank
--------------------

@ENA
@NOERROR
@FTP SRI-NIC.ARPA
*dummy
*set no conf all
*get ps:<kcc-5>*.*.0 ps:<kcc-5>
*get ps:<kcc-5.include>*.*.0 ps:<kcc-5.include>
*get ps:<kcc-5.include.sys>*.*.0 ps:<kcc-5.include.sys>
*get ps:<kcc-5.fail>*.*.0 ps:<kcc-5.fail>
*get ps:<kcc-5.kcc>*.*.0 ps:<kcc-5.kcc>
*get ps:<kcc-5.lib>*.*.0 ps:<kcc-5.lib>
*get ps:<kcc-5.lib.stdio>*.*.0 ps:<kcc-5.lib.stdio>
*get ps:<kcc-5.lib.math>*.*.0 ps:<kcc-5.lib.math>
*get ps:<kcc-5.lib.usys>*.*.0 ps:<kcc-5.lib.usys>
*get ps:<kcc-5.lib.network>*.*.0 ps:<kcc-5.lib.network>
*get ps:<kcc-5.lib.pml>*.*.0 ps:<kcc-5.lib.pml>
*get ps:<kcc-5.lib.test>*.*.0 ps:<kcc-5.lib.test>
*ex
25-Apr-88 23:03:10-PDT,1058;000000000001
Received: from MC.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Mon 25 Apr 88 23:02:20-PDT
Received: from AI.AI.MIT.EDU (CHAOS 3130) by MC.LCS.MIT.EDU 26 Apr 88 00:59:34 EDT
Date: Tue, 26 Apr 88 01:02:29 EDT
From: Alan Bawden <[email protected]>
Subject:   So it wasn't my problem after all...
To: [email protected]
Message-ID: <[email protected]>

[ Apologies to those of you who will get this twice, I incorrectly assumed 
  that Bug-KCC was defined on XX.LCS.MIT.EDU. ]

I find that even with the most recent KCC release, the following:

    extern void padcount();

    void screw(val, cnt)
      int val, cnt;
    {
	int nread;

	nread = ((val > 0) ? val - 1 : val + cnt);
	padcount(nread);
    }

compiles into

    screw:
	    SKIPG 1,-1(17)	; SKIPG 5,-1(17) would fix it
	     SKIPA 5,-2(17)
	     SOSA 5,5		; SOSA 5,1 would fix it
	     ADD 5,-1(17)
	    PUSH 17,5
	    PUSH 17,5
	    PUSHJ 17,padcou
	    ADJSP 17,-2
	    POPJ 17,

I am impressed at just how clever kcc is -trying- to be here.


26-Apr-88 23:29:03-PDT,703;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Tue 26 Apr 88 23:25:59-PDT
Date: Wed, 27 Apr 1988  00:25 MDT
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: KCC-5 problems

I have TGASM set to -1 in CC.EXE.599 (and CCX.EXE).  MACRO complains
that IFIW, %%CODE, and %%DATA are undefined with sources which
compiled cleanly under KCC-4.  Also JSYS.H wants UNV:MONSYM.UNV.  Our
MONSYM.UNV is in SYS: which I believe is the standard path...

Unless I missed it, such differences and what to do about them should
have been pointed out prominently somewhere...

--Frank
26-Apr-88 23:59:02-PDT,866;000000000001
Mail-From: KLH created at 26-Apr-88 23:58:10
Date: Tue, 26 Apr 88 23:58:06 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: KCC-5 problems
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Uh, set TGASM to 1 (the value of the enum TGASM_MACRO), as per INSTAL.DOC
and see if that doesn't make the switch(tgasm) statements in KCC start
working better.  Since KCC can emit code for 3 different assemblers, tgasm
is an enum rather than a simple on-off switch.

As for UNV:MONSYM.UNV, UNV: is the default search path that MACRO itself
uses when none is specified by the user, which is why I used that.
You can just edit your monsym.h file appropriately until we find out
what the real "standard" (if anything) is...
-------
27-Apr-88 12:54:30-PDT,600;000000000001
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Wed 27 Apr 88 12:51:43-PDT
Date: Wed, 27 Apr 1988  13:51 MDT
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   Ken Harrenstien <[email protected]>
Cc:   [email protected], [email protected]
Subject: KCC-5 problems
In-reply-to: Msg of 27 Apr 1988  00:58-MDT from Ken Harrenstien <KLH at SRI-NIC.ARPA>

Ken,

Setting TGASM to 1 indeed solved the undefined problems.  And, I
defined UNV: to SYS: to solve the other problem, for now.  Thanks for
the quick reply!

--Frank
27-Apr-88 13:49:35-PDT,807;000000000001
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Wed 27 Apr 88 13:44:15-PDT
Date: Wed 27 Apr 88 16:46:10-EDT
From: Rob Austein <[email protected]>
Subject: Re: KCC-5 problems
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Frank,

If I recall the MACRO documentation (last read in 1982 or thereabouts),
the SEARCH pseduo-op in MACRO-20 looks for the target name first in DSK:,
then in SYS: and UNV:, I think in that order.  Some sites (eg, XX) do
keep the universals in UNV: in an attempt to cut down on the clutter
in the SYS: directories.  You can always define UNV: to be SYS: unless
you're using it for something completely different.

--Rob
-------
27-Apr-88 15:34:52-PDT,1359;000000000000
Received: from MC.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Wed 27 Apr 88 15:31:09-PDT
Received: from AI.AI.MIT.EDU (CHAOS 3130) by MC.LCS.MIT.EDU 27 Apr 88 18:06:51 EDT
Received: from SRI-NIC.ARPA (TCP 1200000063) by AI.AI.MIT.EDU 26 Apr 88 21:39:02 EDT
Date: Tue, 26 Apr 88 18:30:48 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: So it wasn't my problem after all...
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Arrrgh.  I suppose I should have expected that the first bug would show
up just after I made the first tape dump of the distribution.  Fortunately
I hadn't mailed it yet, so I got a chance to do it all over again.

Thanks for the simple test case; that bug is fixed as of KCC 601.
(cregok() in CCCREG was being unduly optimistic.  The code it now
produces wins by changing all of the regs to 5 (or whatever) instead
of stopping halfway.)

The KCC-5 source distribution has been updated to reflect the fix.
I added the file KCCDIST:-FTP-.MIC which may help some people get the
stuff.  I had a hard time deciding which of various methods to use (.CTL?
FTP take of .CMD?  EXEC take of .CMD?  Which FTP?  Logical names?) and
finally just put together a .MIC that invites you to edit it.
-------


 1-May-88 07:31:02-PDT,1403;000000000000
Received: from MCC.COM by SRI-NIC.ARPA with TCP; Sun 1 May 88 07:29:03-PDT
Date: Sun 1 May 88 09:29:14-CDT
From: Clive Dawson <[email protected]>
Subject: KCC Logical name bug
To: [email protected]
cc: [email protected]
Message-ID: <[email protected]>

Ken-
  I've started playing with KCC in order to get SRA's domain
resolver running.  

  I ran into an interesting problem which took a bit of digging to
track down.  As a newcomer, I don't know if this has been covered
on this list before, but in any case it's probably worth a bug-fix,
or at the very least a warning in the INSTAL.DOC file.

  I had C: defined to be <KCC.INCLUDE>.  Attempts to compile
anything with an Include statement of the form

	#include <sys/filename>

failed.  I took a look at the GTJFN and noticed it was using a
filespec of the form

	<KCC.INCLUDE>:<KCC.INCLUDE.sys>types.h

which indicated that the logical name expansion was getting screwed
up.  Sometime later in the depths of OPEN, _GET_TRICKY, etc., I
discovered that the logical definition of C: had better have
an explicit device.

I changed C: to be PS:<KCC.INCLUDE> and all works fine now.

Hmmmm...A warning in INSTAL.DOC would help make sure that the
system-wide definition is right, but it wouldn't protect users who get
"sloppy" with job-wide definitions of C:, etc.

Cheers,

Clive Dawson
-------
 5-May-88 09:39:22-PDT,4647;000000000000
Received: from SCIENCE.UTAH.EDU by SRI-NIC.ARPA with TCP; Thu, 5 May 88 09:35:29 PDT
Date: Wed 4 May 88 19:30:01-MDT
From: "Nelson H.F. Beebe" <[email protected]>
Subject: ungetc() doesn't backup file pointer for ftell()
To: [email protected]
cc: [email protected]
X-US-Mail: "Center for Scientific Computing, South Physics, University of Utah, Salt Lake City, UT 84112"
X-Telephone: (801) 581-5254
Message-ID: <[email protected]>

In KCC 4 and 5, ungetc() doesn't backup the file pointer for
ftell(); it did so correctly in KCC 3.  This prevents my TeX
DVI drivers from running with KCC 4 or 5.

Here is a PHOTO log with a simple test program; the file it
reads can be any 8-bit file you like.


[PHOTO:  Recording initiated  Wed 4-May-88 7:22PM]

 TOPS-20 Command processor 5(712)
@type bug2.c
-------------------
APS:<BEEBE>BUG2.C.2
-------------------

#include <stdio.h>


int
main(argc,argv)
int argc;
char* argv[];
{
    FILE* fp;
    long k;
    long p;
    int c;

    fp = fopen("APS:<TEX.CM>CMBX12.300PK","rb8");
    
    for (k = 0; k < 256; k += 15)
    {
	fseek(fp,k,0);
	c = getc(fp);
	ungetc(c,fp);
	p = ftell(fp);
	if (p != k)
		printf("ungetc() failure: fseek to %ld, ftell says %ld, byte = 0
%o\n",
			k,p,c);
    }
    fclose(fp);
    return (0);
}
@v c:kcc.exe

   FES:<KCC-5>
 KCC.EXE.602;P777752      170 87040(36)  29-Apr-88 18:09:17 BEEBE     
@bug2
ungetc() failure: fseek to 0, ftell says 1, byte = 0367
ungetc() failure: fseek to 15, ftell says 16, byte = 0165
ungetc() failure: fseek to 30, ftell says 31, byte = 046
ungetc() failure: fseek to 45, ftell says 46, byte = 0376
ungetc() failure: fseek to 60, ftell says 61, byte = 047
ungetc() failure: fseek to 75, ftell says 76, byte = 0362
ungetc() failure: fseek to 90, ftell says 91, byte = 0174
ungetc() failure: fseek to 105, ftell says 106, byte = 0102
ungetc() failure: fseek to 120, ftell says 121, byte = 0151
ungetc() failure: fseek to 135, ftell says 136, byte = 0172
ungetc() failure: fseek to 150, ftell says 151, byte = 0345
ungetc() failure: fseek to 165, ftell says 166, byte = 0300
ungetc() failure: fseek to 180, ftell says 181, byte = 0142
ungetc() failure: fseek to 195, ftell says 196, byte = 0327
ungetc() failure: fseek to 210, ftell says 211, byte = 041
ungetc() failure: fseek to 225, ftell says 226, byte = 050
ungetc() failure: fseek to 240, ftell says 241, byte = 015
ungetc() failure: fseek to 255, ftell says 256, byte = 0153
@
@def c: cold:
@v cold:kcc

   PS:<SUBSYS.KCC3>
 KCC.EXE.561;P777752      147 75264(36)  11-May-87 17:55:00 KLH@SRI-NIC 
   .INFO.4;P777752         39 98567(7)   16-May-87 10:52:57 BEEBE     
   .TECO.1;P777752          1 165(7)     12-Feb-87 12:35:41 BEEBE     
   .VMSHELP.6;P777752      36 90179(7)   16-May-87 10:52:22 BEEBE     

 Total of 223 pages in 4 files
@del bug2.rel
 BUG2.REL.1 [OK]
@kcc bug2
KCC:	bug2
<BEEBE>BUG2.PRE.1
<BEEBE>BUG2.FAI.1
FAIL:  bug2
LINK:	Loading
@bug2
@! That was KCC version 3
@
@def c:
@v c:kcc.exe

   PS:<SUBSYS.KCC>
 KCC.EXE.586;P777752      158 80896(36)   9-Mar-88 19:03:02 KLH       
      .590;P777752        160 81920(36)   8-Apr-88 05:18:30 BEEBE     
      .593;P777752        165 84480(36)  15-Apr-88 03:33:14 BEEBE     

 Total of 483 pages in 3 files
@kcc bug2
KCC:	bug2
<BEEBE>BUG2.PRE.1
<BEEBE>BUG2.FAI.1
FAIL:  bug2
LINK:	Loading
@bug2
ungetc() failure: fseek to 0, ftell says 1, byte = 0367
ungetc() failure: fseek to 15, ftell says 16, byte = 0165
ungetc() failure: fseek to 30, ftell says 31, byte = 046
ungetc() failure: fseek to 45, ftell says 46, byte = 0376
ungetc() failure: fseek to 60, ftell says 61, byte = 047
ungetc() failure: fseek to 75, ftell says 76, byte = 0362
ungetc() failure: fseek to 90, ftell says 91, byte = 0174
ungetc() failure: fseek to 105, ftell says 106, byte = 0102
ungetc() failure: fseek to 120, ftell says 121, byte = 0151
ungetc() failure: fseek to 135, ftell says 136, byte = 0172
ungetc() failure: fseek to 150, ftell says 151, byte = 0345
ungetc() failure: fseek to 165, ftell says 166, byte = 0300
ungetc() failure: fseek to 180, ftell says 181, byte = 0142
ungetc() failure: fseek to 195, ftell says 196, byte = 0327
ungetc() failure: fseek to 210, ftell says 211, byte = 041
ungetc() failure: fseek to 225, ftell says 226, byte = 050
ungetc() failure: fseek to 240, ftell says 241, byte = 015
ungetc() failure: fseek to 255, ftell says 256, byte = 0153
@! That was KCC version 4
@pop

[PHOTO:  Recording terminated  Wed 4-May-88 7:25PM]
-------
 5-May-88 09:54:17-PDT,1273;000000000000
Mail-From: KLH created at  5-May-88 09:50:34
Date: Thu, 5 May 88 09:50:20 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: ungetc() doesn't backup file pointer for ftell()
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

The value of ftell() when there are ungetc'd chars to be read is
unspecified in H&S and previous versions of the ANSI draft.  The latest
draft has this to say:

"For a text stream, the value of its file position indicator after a successful
call to the ungetc function is unspecified until all pushed-back characters are
read or discarded.  For a binary stream, its file position indicator is
decremented by each successful call to the ungetc function; if its value was
zero before a call, it is indeterminate after the call."

We haven't gotten around to doing much about ANSI, really; I don't think it
is wise to rely on anything in that draft until they really pass it as a
standard.  (For example, I heartily hope that they come to their senses and
flush the "noalias" abomination.)

But since you already depended on something that the draft now supports, I will
take a look at it.
-------
 5-May-88 10:24:48-PDT,1463;000000000000
Received: from SCIENCE.UTAH.EDU by SRI-NIC.ARPA with TCP; Thu, 5 May 88 10:23:23 PDT
Date: Thu 5 May 88 11:22:46-MDT
From: "Nelson H.F. Beebe" <[email protected]>
Subject: Re: ungetc() doesn't backup file pointer for ftell()
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
X-US-Mail: "Center for Scientific Computing, South Physics, University of Utah, Salt Lake City, UT 84112"
X-Telephone: (801) 581-5254
Message-ID: <[email protected]>


>> "For a binary stream, its file position indicator is
>> decremented by each successful call to the ungetc function;
>> if its value was zero before a call, it is indeterminate
>> after the call."

This implies in my case that ftell() must work.  Without
this feature, it is absolutely impossible to process TeX DVI
and font files, because reading of unbounded sequences is
necessary; the input determines when you have read too far,
and then you have to do an ungetc() so that a subsequent
ftell() tells you where you are.  Because ftell() is
permitted to return a magic cookie that is not the byte
position, you cannot add -1 to the ftell() value to get the
real pointer if ungetc() fails to reset it.  Actually, any
system that returns a magic cookie instead of a byte
position will be unusable for TeX DVI and font files, too,
because they both contain byte pointers into themselves.
-------
 5-May-88 10:34:31-PDT,748;000000000000
Received: from THOR.HPL.HP.COM by SRI-NIC.ARPA with TCP; Thu, 5 May 88 10:31:38 PDT
Mail-From: WHITE created at  5-May-88 10:00:51
Date: Thu 5 May 88 10:00:51-PDT
From: Vic White <[email protected]>
Subject: LIBTRM and LIBTMX
To: Bug-KCC@SRI-NIC
cc: [email protected]
Message-ID: <[email protected]>
ReSent-Date: Thu 5 May 88 10:29:16-PDT
ReSent-From: Vic White <[email protected]>
ReSent-To: Bug-KCC@SRI-NIC
ReSent-Message-ID: <[email protected]>

    Are there any sources for DB:<KCC-5.INCLUDE>LIBTRM and LIBTMX?
We run KCC with logical name 'KCC:' (rather than 'C:') as the default
for include and library files.  I need to do the same for these.
Thanks.

Vic White
-------
 5-May-88 10:49:20-PDT,1250;000000000000
Mail-From: KLH created at  5-May-88 10:45:41
Date: Thu, 5 May 88 10:45:25 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: ungetc() doesn't backup file pointer for ftell()
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Here is the fix (reflected in our C:LIBC.REL, but not in the distribution):

;COMPARISON OF PS:<C.LIB.STDIO>FTELL.C.22 AND PS:<C.LIB.STDIO>FTELL.C.23
;OPTIONS ARE    /3

**** FILE PS:<C.LIB.STDIO>FTELL.C.22, 1-40 (1276)
 *	ungetc.  We ignore all pushed-back chars in calculating the pointer.
 */
	    cur_cnt = (f->sioflgs & _SIOF_PBC) ? f->sio2cnt : f->siocnt;
**** FILE PS:<C.LIB.STDIO>FTELL.C.23, 1-40 (1276)
 *	ungetc.  ANSI says pushed-back chars should be included for binary
 *	streams, though the pointer value is unspecified if you ungetc
 *	at position 0.  For text streams the behavior is unspecified; we
 *	try to do the same thing as for binary (because that's simplest) but
 *	the results will probably not be useful.
 */
	    cur_cnt = (f->sioflgs & _SIOF_PBC)
			? f->sio2cnt + f->siocnt	/* Include pushback */
			: f->siocnt;
***************

-------
 5-May-88 10:49:43-PDT,411;000000000000
Mail-From: KLH created at  5-May-88 10:48:10
Date: Thu, 5 May 88 10:48:00 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: LIBTRM and LIBTMX
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

They are in <KCC-5.LIB> and both have .MIC files there, just as for LIBC.
-------
 9-May-88 13:09:15-PDT,438;000000000000
Received: from THOR.HPL.HP.COM by SRI-NIC.ARPA with TCP; Mon, 9 May 88 11:10:37 PDT
Date: Mon 9 May 88 11:09:04-PDT
From: Vic White <[email protected]>
Subject: KCC-5: LIBTRM and LIBTMX
To: Bug-KCC@SRI-NIC
cc: [email protected]
Message-ID: <[email protected]>

I went back to the <KCC-5> tree and can only find .DOC and .REL
files ... nothing that looks like to stuff to rebuild them.

Vic
-------
 9-May-88 14:04:12-PDT,743;000000000000
Mail-From: KLH created at  9-May-88 14:03:33
Date: Mon, 9 May 88 14:02:57 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: KCC-5: LIBTRM and LIBTMX
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

*Sigh* You're right, the .MIC files were missing.  I distinctly remembered
putting in a special line in the .MIC file that generates the distribution
to make sure that those .MIC files were included; however, I forgot that I
did this AFTER creating the initial distribution.  Another reason I try
to avoid incremental updates...  anyway, I put them there.
<KCC-5.LIB>LIBTMX.MIC and LIBTRM.MIC.
-------
15-May-88 22:42:05-PDT,1119;000000000000
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sun, 15 May 88 22:38:12 PDT
Date: Sun, 15 May 1988  23:38 MDT
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
Subject: debugging a saved image?

We are still beta testing a version of John Gilmore's gnu uucp and
discovered a new crash point.  Because the protocol cannot be easily
emulated to get the the same point by hand, I have caused an
EXEC-level SAVE to be taken.  But, that turns out to be of little help
- none of the registers are saved and I'm not smart about figuring out
how to walk-back the stack nor where it is.  I tried advising the job,
but when the program on the other end times out, the detached job
output hangs.  I suppose I *should* have UNATTACHed the job and then
advised an empty tty and attached to it.  At least I would have some
register values to examine...  The program aborts trying to execute a
0 at an unallocated region of memory.  Is there a better way or is
there *any* way to backtrace with the save I already have?

--Frank
15-May-88 23:46:52-PDT,1179;000000000000
Mail-From: KLH created at 15-May-88 23:44:01
Date: Sun, 15 May 88 23:43:25 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: debugging a saved image?
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Not really.  Without the contents of register 17 (the stack pointer) all you
can do is look for the highest-used place on the stack.  The stack is in
section 2 if extended, else it is in the space between highest data and
location 400000.  Assuming it's the latter, look for the first used page
prior to page 400; the top of the stack (actually, the highest point ever
hit by the stack) will be someplace there.  The bottom (start) of the stack
can be determined by looking at the startup code at $$STRT and following
the JRST.  The first several instructions set up the stack and you can
figure out from the data it uses what the initial stack pointer value was.

It would be much easier to figure out a way of finding the contents of
register 17 prior to dumping.  Even if only by using the exec-level
EXAMINE command.
-------
16-May-88 08:11:58-PDT,799;000000000000
Received: from Score.Stanford.EDU by SRI-NIC.ARPA with TCP; Mon, 16 May 88 08:07:06 PDT
Date: Mon 16 May 88 08:05:19-PDT
From: Stu Grossman <[email protected]>
Subject: Re: debugging a saved image?
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

1) You could do an exec level EXAMINE command to read the registers.  The
   stack register is probably the most important one.
2) Add a small routine to dump the registers into a safe place, and then
   do a SAVE% jsys.  If you put the start address of this routine into .JBREN
   (location 124), then you will be able to invoke this routine from the EXEC
   simply by doing a REENTER command.

			Stu
-------
20-May-88 23:23:07-PDT,2642;000000000000
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Fri, 20 May 88 22:54:16 PDT
Date: Sat, 21 May 1988  01:54 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: Thoughts on JSYS.H

So, I've been playing around with putting all the monitor symbols that
CHIVES needs into the code via the monsym() and monsymdefined() macros
(great stuff, BTW, monsymdefined() makes possible some things that
hadn't occured to me before).  The one antediluvian relic is JSYS.H.

Now, I can ignore this, pretty much, since I happen to know that the
current JSYS.C code will not do anything horrible if I just use
monsym() to get the JSYS numbers.  But it's ugly, and it doesn't
address the issue of people who want to do things by the book but who
use monitor calls that aren't installed at SRI (CHANM%? GTBLT%?).
Installing the site specific calls is painful and violates the
principle of Letting The Machine Do The Dirty Work.

I submit that this JSYS class stuff is of no concern to anything but
the JSYS.C code and thus should be kept entirely internal to JSYS.C.
Yes, that means a few more instructions, but I count over 100 lines of
code in the jsys() function as currently implemented so I don't think
this can be considered a serious issue.

For reference, the few relevant lines from JSYS.H:

 *	The JSYS classes are:
 *
 *	class 0		jsys returns +1 always, generating an illegal
 *			instruction on error
 *	class 1		jsys returns +1 on error, +2 on win
 *	class 2		special class for ERSTR%
 *	class 3		special class for SIBE% and SOBE%
 *	class 4		special class for SOBF%

Classes 2, 3, & 4 are amenable to simple CAIE/CAIN testing.  The
distinction between class 0 and class 1 is not horribly useful on
TOPS-20 (any normal JSYS will work fine if it goes through the class 0
code) but I suppose that if you're serious about supporting TENEX we
have to worry about this.

Currently, the highest allocated JSYS number that I know of is MDDT%
(JSYS 777); I suppose this might increase in some mythical later
version, but not by much, given that doing so increases the length of
the monitor's JSTAB dispatch table.  Assuming for the moment that
MDDT% will continue to be the highest numbered JSYS, a little
arithmetic shows that the class 0/class 1 information can be stored in
a 017 word bitvector.  Seems acceptable.

I'm willing to rewrite JSYS.C to support this scheme.  I wanted to
check first to see if anybody sees any problems with it.

Help stamp out JSYS.H in our lifetime!

--Rob
22-May-88 01:02:02-PDT,1742;000000000000
Received: from SCIENCE.UTAH.EDU by SRI-NIC.ARPA with TCP; Sun, 22 May 88 00:37:59 PDT
Date: Sun 22 May 88 01:38:08-MDT
From: Pieter <[email protected]>
Subject: "offsetof" macro
To: [email protected]
cc: [email protected]
Snail: Center for Scientific Computation
Snail: 224 Physics South
Snail: University of Utah
Snail: Salt Lake City, UT 84112, USA
Telephone: (801) 581-6286
Message-ID: <[email protected]>

This may or may not be a bug, but is something which I
would like to have available.

The following is a sample of some code I am trying to
get running on the 20.  It compiles ok on our Suns, but
doesn't with KCC.  The "offsetof" macro is actually defined
in the X3J11/88-003 draft of C.  The text says:

		offsetof(type, identifier)

	which expands to an integral constant expression that has
	type "size_t", the value of which is the offset in bytes, to
	the structure member (designated by "identifier"), from the
	beginning of its structure (designated by "type").

There are several possible definitions given in the draft for
"offsetof".  I've include the two which make the most sense to
me.

----------------------------------------------------------------------
typedef struct {
  unsigned short a;
  unsigned short b;
  unsigned short c;
} s;

#define offsetof(s_name, m_name) ((int)&(((s_name*)0)->m_name))
/*#define offsetof(s_name, m_name) ((int)(&(((s_name*)0)->m_name) - &(s_name*)0))*/

int offsets[] = {
  offsetof(s,a),
  offsetof(s,b),
  offsetof(s,c)
};
----------------------------------------------------------------------
If there is another way to do this, I'll gladly use it.

Pieter
[email protected]
-------
22-May-88 13:14:52-PDT,1472;000000000000
Mail-From: KLH created at 22-May-88 13:14:19
Date: Sun, 22 May 88 13:14:10 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: "offsetof" macro
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

There isn't any way to achieve the effect of offsetof(), other than by
declaring a dummy example of the structure and using that at run time.
The "suggested forms" of that macro rely on non-portable artifacts of the
machine, in particular the use of byte addressing as the only form of
addressing.

You can do something like the following:

#define myoffset(s,m)	((char *)(&s.m) - (char *)(&s))
static struct foo foo;
	/* ... */
	offset = myoffset(foo,member);

That is, define an instance of "foo" for each "struct foo" you want to apply
the macro to.  Then take the difference of two pointers to the member and
to the start of the structure; these must be char pointers in order to get
the result in terms of # chars.

This obviously will not work for bitfields or non-standard char sizes.
Eventually, if "offsetof" makes it into the final draft standard (hmm, sort
of a contradiction there), KCC will implement it with a built-in construct.
(Or I may have it try to make sense of the tricks done with NULL pointers;
not easy since most operations on a NULL pointer just result in another
NULL pointer.)
-------
22-May-88 13:54:49-PDT,622;000000000000
Received: from Score.Stanford.EDU by SRI-NIC.ARPA with TCP; Sun, 22 May 88 13:52:30 PDT
Date: Sun 22 May 88 13:51:36-PDT
From: Stu Grossman <[email protected]>
Subject: Re: Thoughts on JSYS.H
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Actually, it would be rather difficult (if not impossible) to have a JSYS
number greater than 777.  The reason for this is that JSYSi 1000 and above
are 'user defined', and must remain so for certain programs to operate
correctly.
				Stu
-------
23-May-88 20:03:59-PDT,601;000000000000
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Mon, 23 May 88 20:02:35 PDT
Date: Mon, 23 May 1988  23:01 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
Subject: Code to eliminate JSYS.H

The code to eliminate the need for JSYS.H is available on a
use-at-own-risk basis from XX:<SRA.77>.  (Ken, this is a slightly
different version than the files I pointed you at this afternoon.)

The files of interest are:
	JSYS.C			;New version of jsys() routine
				;

	MONSYM.H		;JSYS_OKINT moved here from JSYS.H
23-May-88 20:44:01-PDT,1476;000000000000
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Mon, 23 May 88 20:42:22 PDT
Date: Mon, 23 May 1988  23:41 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
Subject: Code to eliminate JSYS.H

[Apologies if a partial copy of this made it out, typing spaz....]

The code to eliminate the need for JSYS.H is available on a
use-at-own-risk basis from XX:<SRA.77>.  Ken, this is a slightly
different version than the files I pointed you at this afternoon.

The files of interest are:
	JSYS.C			;New version of jsys() routine
	JSYS-BITVECTOR.H	;Bitvector of class 1 JSYS numbers
	DEFJS.C			;Little program to generate
				;JSYS-BITVECTOR.H automagicly
	MONSYM.H		;JSYS_OKINT moved here from JSYS.H

These are for KCC-5; they will not work with earlier versions.  JSYS.C
and MONSYM.H are plug-ins for the distributed versions, the others are
only used when building LIBC.REL.

With this stuff in place, JSYS.H is no longer necessary except to
support old programs.  Old programs will continue to work with the new
jsys() routine (the JSYS_CLASS passed in the call will be ignored).

New programs can do

	jsys(monsym("name%"),acblock)

and expect the right thing to happen.  I added a macro to MONSYM.H so
that you can do

	JSYS("name%",acblock)

It's under a #ifndef JSYS/#endif conditional out of paranoia that it
might conflict with some existing usage.

--Rob
29-May-88 13:43:31-PDT,1080;000000000000
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Sun, 29 May 88 13:42:06 PDT
Date: Sun, 29 May 1988  14:40 MDT
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: Captive user program

I've been modifying a new version of a simple menu program, originally
targetted for the Unix environments, to make it a locked-in program.
In the previously modified version, I had used some assembly language
hacks to force raw mode and ignore interrupts (stolen from TELNET).
With this version, I now want to use the available C signal() and
ioctl() constructs instead.  The catch is that I cannot catch ^C
interrupts without going to raw mode (an apparent contradiction).
Also, if the menu lets the user make a system() call, two ^Cs not only
abort the lower fork, but also abort the menu program as well!  Have I
overlooked something or do I need to revert to assembly language and
possibly interfere with other PSI setups in the runtime code?

--Frank
 1-Jun-88 15:49:09-PDT,1294;000000000000
Mail-From: KLH created at  1-Jun-88 15:41:01
Date: Wed, 1 Jun 88 15:40:54 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Captive user program
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

I guess I'm not quite sure what it is that needs to be done.  What
were the assembly language hacks you used?  What do you want to happen?
That is, do you want to catch ^C (where?) or just ignore it?
Is there any problem with just ignoring it, as raw mode does (sort of-- it
treats it as input)?

The PSI system in a C program is not turned on unless a signal() or
signal-related call is made.  So if you never use one of these calls, you
can invent and use your own completely independent PSI stuff.

Hmmm, I hadn't thought about system() versus ^C.  The 4.2/4.3 BSD
version of Unix ignores SIGINT and SIGQUIT while waiting for the
inferior fork to terminate.  (In true losing Unix fashion, there is a
hole between the fork and the signal calls during which a interrupt
could clobber the parent!)  I could have it invoke STIW% on itself
to turn off the terminal interrupt word bits for SIGINT and SIGQUIT;
would this serve the purpose?
-------
 1-Jun-88 20:41:45-PDT,1106;000000000000
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Wed, 1 Jun 88 20:36:18 PDT
Date: Wed, 1 Jun 1988  21:34 MDT
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   Ken Harrenstien <[email protected]>
Cc:   [email protected], [email protected]
Subject: Captive user program
In-reply-to: Msg of 1 Jun 1988  16:40-MDT from Ken Harrenstien <KLH at SRI-NIC.ARPA>

Ken,

What I want this menu program to do is mimic the EXEC behavior in a
fashion similar to running EXEC in a lower fork, which, in turn, lets
you run other programs, but ^Cs never abort that lower EXEC - only a
POP lets you out.

I suspect your idea of having SIGQUIT and SIGINT be ignored while a
system() is being executed might do the trick.  Will that take care of
two or four ^Cs, though?  But, should I do when it is not running a
system() call?

A further note on system() - really on forkex(): if the program being
run is explicitly named, including the pathname, the pathname doesn't
appear to be stripped of the string handed to rscan...

--Frank
 7-Jun-88 19:18:57-PDT,1220;000000000000
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Tue, 7 Jun 88 19:15:36 PDT
Date: Tue, 7 Jun 1988  20:10 MDT
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: freopen() question

In the public domain compress program, the code is designed to use
freopen() to write to a file, but use stdout conventions.  At then end
of the pass, it does fclose(stdout) so that it can set various
parameters in the fdb.  If there are more arguments given, it attempts
to use freopen() again and fails because stdout out has been closed.

The following test program, given more than one filename as arguments,
succeeds on 4.2bsd and SYSV Release 3.1.1, and generates perror
messages after the first arg has been processed.

--Frank
--------------------

#include <stdio.h>

main(argc, argv)
char *argv[];
{
    int	i;
    char    ofname[100];

    for (i = 1; i < argc; i++) {
	strcpy(ofname, argv[i]);
	if (freopen(ofname, "w8", stdout) == NULL) {
	    perror(ofname);
	    continue;
	}
	fprintf(stderr, "worked on: %s\n", ofname);
	fclose(stdout);
    }
}
====================
11-Jun-88 15:52:06-PDT,1882;000000000000
Received: from clash.cisco.com by SRI-NIC.ARPA with TCP; Sat, 11 Jun 88 15:46:02 PDT
Received: from clutter.cisco.com by clash.cisco.com with TCP; Sat, 11 Jun 88 15:44:01 PDT
To: [email protected]
Subject: scanf bug
Date: Sat, 11 Jun 88 15:45:53 PDT
From: Bill Palmer <[email protected]>

The following program prints out "variable = #tatic" instead of 
the proper "variable = static".

#include <stdio.h>

main()
{
    FILE *f;
    char variable[80];
    int junk;

    f = fopen("bug.input","r");
    fscanf (f,"#define %80s %2d\n", variable, &junk);
    fscanf (f,"#define %80s %2d\n", variable, &junk);
    fscanf (f,"#define %80s %2d\n", variable, &junk);
    if (fscanf(f,"%80s",variable) != 1) {
	fprintf(stderr,"variable = %s\n",variable);
    }
    fprintf(stderr,"variable = %s\n",variable);
}
---bug.input---
#define test_width 16
#define test_height 16
static short test_bits[] = {
   0x0000, 0x0180, 0x1440, 0x0000,
   0x2d70, 0x1c68, 0x1194, 0x21ea,
   0x2bf2, 0x0024, 0x0df0, 0x06c0,
   0x0ae4, 0x0184, 0x0718, 0x0000};


In scanf.c, when doing the literal matching, if the character from the 
format string does not match the character from the stream, the character
from the format string is pushed back into the stream.  Oops.


;COMPARISON OF MATHOM:<WHP4.KCC-5.LIB.STDIO>SCANF.C.187 AND MATHOM:<WHP4.KCC-5.LIB.STDIO>SCANF.C.188
;OPTIONS ARE    /3

**** FILE MATHOM:<WHP4.KCC-5.LIB.STDIO>SCANF.C.187, 3-10 (2331)
    int c;
**** FILE MATHOM:<WHP4.KCC-5.LIB.STDIO>SCANF.C.188, 3-10 (2331)
    int c,ch;
***************

**** FILE MATHOM:<WHP4.KCC-5.LIB.STDIO>SCANF.C.187, 3-121 (6190)
	else if (c != getc(sf.stream)) {
	    ungetc(c, sf.stream);
**** FILE MATHOM:<WHP4.KCC-5.LIB.STDIO>SCANF.C.188, 3-121 (6193)
	else if (c != (ch = getc(sf.stream))) {
	    ungetc(ch, sf.stream);
***************

11-Jun-88 15:52:29-PDT,479;000000000000
Received: from clash.cisco.com by SRI-NIC.ARPA with TCP; Sat, 11 Jun 88 15:48:23 PDT
Received: from clutter.cisco.com by clash.cisco.com with TCP; Sat, 11 Jun 88 15:46:24 PDT
To: [email protected]
Subject: kcc bug
Date: Sat, 11 Jun 88 15:48:16 PDT
From: Bill Palmer <[email protected]>

KCC isn't happy about the ++-> construct in the following code.

struct foo {
    int bar;
    int baz;
}

main()
{
    struct foo *glork;

    glork++->baz = 0;
}
11-Jun-88 16:00:51-PDT,479;000000000000
Received: from clash.cisco.com by SRI-NIC.ARPA with TCP; Sat, 11 Jun 88 15:56:26 PDT
Received: from clutter.cisco.com by clash.cisco.com with TCP; Sat, 11 Jun 88 15:54:24 PDT
To: [email protected]
Subject: kcc bug
Date: Sat, 11 Jun 88 15:56:15 PDT
From: Bill Palmer <[email protected]>

KCC isn't happy about the ++-> construct in the following code.

struct foo {
    int bar;
    int baz;
}

main()
{
    struct foo *glork;

    glork++->baz = 0;
}
13-Jun-88 10:17:12-PDT,1108;000000000000
Mail-From: KLH created at 13-Jun-88 10:11:29
Date: Mon, 13 Jun 88 10:11:24 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: kcc bug (p++->)
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: Message from "Bill Palmer <[email protected]>" of Sat, 11 Jun 88 15:52:28 PDT
Message-ID: <[email protected]>

I'm not too happy about p++-> either, since it might tempt people to
think that ++p-> similarly increments p (it doesn't) rather than the
thing p points to.  When I checked the references, I found that both
K&R and H&S v1 prohibit that sort of syntax; the left-hand side of a
-> must be a "primary" expression.  However, both H&R v2 and the X3J11
DPANS document now say that it can be a "postfix" expression, which
includes p++.

I'm surprised this change wasn't flagged more explicitly; the rationale
doesn't mention it at all.  But anyway, I guess I'll change KCC.  I may
make it dependent on the portability level.  Needless to say, anyone who
actually uses such code is probably asking for trouble when porting.
-------
13-Jun-88 10:17:39-PDT,475;000000000000
Mail-From: KLH created at 13-Jun-88 10:15:44
Date: Mon, 13 Jun 88 10:15:35 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: scanf bug
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: Message from "Bill Palmer <[email protected]>" of Sat, 11 Jun 88 15:52:05 PDT
Message-ID: <[email protected]>

Thanks for the bug report.  Thanks even more for the bug fix!!
I've incorporated it in our source.
-------
13-Jun-88 11:23:18-PDT,1012;000000000000
Mail-From: KLH created at 13-Jun-88 10:41:27
Date: Mon, 13 Jun 88 10:33:08 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: freopen() question
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Sorry, but judging from the minutes of the most recent X3J11 meeting, the
C standard committee feels that "fclose renders its FILE argument undefined
and unusable.  There is no sense in talking about a FILE argument designating
a closed file, either in fclose or freopen."

It happens to be a peculiarity that stdin, stdout, and stderr refer to
static objects in some implementations.  This is not mandated anywhere
and cannot be relied on by portable code.  Thus, KCC is doing the
right thing, and the compress program will have to be changed; not an
unusual situation, as non-portable conventions seem to be the single
biggest problem with public domain code.
-------
29-Jun-88 10:31:30-PDT,749;000000000000
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Wed, 29 Jun 88 10:28:53 PDT
Date: Wed, 29 Jun 1988  13:28 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: whence strtok() ?

I was groveling through <.LIB>STRING.C trying to figure out the exact
right combination of strspn() and strbrk() and strcspn() calls to do
what I would like to think is some simple parsing, and lo, there's
this strtok() routine that does exactly what I want.  It even works
when I try it.

So now my only question is, where does this routine come from?
Neither BSD 4.3 man nor CARM (v1) knows about it.  Is this a CARM v2
function or KCC-only?
29-Jun-88 10:51:06-PDT,1803;000000000000
Mail-From: IAN created at 29-Jun-88 10:46:29
Date: Wed, 29 Jun 88 10:46:04 PDT
From: Ian Macky <[email protected]>
Subject: Re: whence strtok() ?
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

strtok() appears in section 15.7 (page 302) of CARM II, and is NOT shown
as an ANSI addition, so it must be older...

    char *strtok(str, set)
    char *str, *set;

"   The function strtok may be used to separate a string str into tokens
separated by characters from the string set.  A call is make on strtok for
each token, possibly changing the value of set in successive calls.  The
first call includes the string str; subsequent calls pass a null pointer
as the first argument, directing strtok to continue from the end of the
previous token.
    More precisely, if str is not null then strtok first skips over all
characters in str that are also in set.  If all the characters of str
occur in set then strtok returns a null pointer and an @i(internal state
pointer) is set to a null pointer.  Otherwise, the ISP is set to point
to the first character of str not in set and execution continues as if
str has been null.
    If str is null and the ISP is null then strtok returns a null pointer
and the ISP is unchanged.  If str is null but the ISP is not null, then
the function searches beginning at the ISP for the first character
contained in set.  If such a character is found, the character is
overwritten with '\0', strtok returns the value of the ISP, and the ISP
is adjusted to point to the character immediately following inserted null
character.  If no such character is found, strtok returns the value of
the ISP and the ISP is set to null."

--ian
-------
29-Jun-88 14:44:05-PDT,656;000000000000
Mail-From: KLH created at 29-Jun-88 14:40:20
Date: Wed, 29 Jun 88 14:39:12 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: whence strtok() ?
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

To add to Ian's response: strtok() is in the ANSI draft, although it
did not originate there, as did strstr().  It comes from System V, and
unfortunately appears to represent typical Unix brain-damaged design;
namely, it is not re-entrant, uses static data cells, clobbers the
string pointed to, and so forth.  Sigh.
-------
30-Jun-88 10:10:52-PDT,3963;000000000000
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Thu, 30 Jun 88 10:07:54 PDT
Date: Thu 30 Jun 88 13:05:27-EDT
From: Rob Austein <[email protected]>
Subject: [Jan Michael Rynning <Jan-Rynning%[email protected]>: Compiler and runtime library fix for KCC.]
To: [email protected]
Message-ID: <[email protected]>

Jan has been installing CHIVES in Sweden, I'm pretty sure he's running
the old XX KCC-3 with MIT bugfixes and patches.  I'm going to be
sending them a tape with, among other things, KCC-5.

Anyway, thought I'd pass this along.

--Rob
                ---------------

Return-Path: <@MITVMA.MIT.EDU:[email protected]>
Received: from MITVMA.MIT.EDU by XX.LCS.MIT.EDU with TCP/SMTP; Thu 30 Jun 88 12:56:44-EDT
Received: from MITVMA.MIT.EDU by MITVMA.MIT.EDU (IBM VM SMTP R1.1) with BSMTP id 8207; Thu, 30 Jun 88 12:57:37 EDT
Received: from SEKTH.BITNET by MITVMA.MIT.EDU (Mailer X1.25) with BSMTP id
 8206; Thu, 30 Jun 88 12:57:36 EDT
Received: from kth.se by KTH-BITNET-GATEWAY ; 30 Jun 88 15:36:30 GMT
Date: Thu 30 Jun 88 17:36:41
From: Jan Michael Rynning <Jan-Rynning%[email protected]>
Subject: Compiler and runtime library fix for KCC.
To: [email protected], [email protected]
Organization: Royal Institute of Technology, Stockholm, Sweden.
Address: NADA, KTH, S-100 44 Stockholm, Sweden.
Telephone: +46-8-7906288
Message-Id: <[email protected]>

While I'm at it, here are two more fixes, one for the KCC compiler, and one
for the runtime system.
-------------------------------------------------------------------------------
In file CCOUT.C:
static char * macjbp[] = {      "ADJBP",
        "EXTERN $ADJBP",        /* Declare extern routine to simulate it */
        "MOVE   16,MEM",        /* Do this before EXCH.  Get byte pointer */
        "EXCH   15,AC",         /* Put count into expected reg, save AC15 */
        "PUSHJ  17,$ADJBP",     /* Call $ADJBP to simulate byte ptr add */
        "EXCH   15,AC",         /* restore AC15 and get adjusted bp in reg */
        NULL
};
The rest of the code generation refers to "M" and "A", so change it to:
static char * macjbp[] = {      "ADJBP",
        "EXTERN $ADJBP",        /* Declare extern routine to simulate it */
        "MOVE   16,M",          /* Do this before EXCH.  Get byte pointer */
        "EXCH   15,A",          /* Put count into expected reg, save AC15 */
        "PUSHJ  17,$ADJBP",     /* Call $ADJBP to simulate byte ptr add */
        "EXCH   15,A",          /* restore AC15 and get adjusted bp in reg */
        NULL
};
We have KA's and KI's, where this is needed.
-------------------------------------------------------------------------------
In file CRT.C:
SSTART: RESET%                  /* Initialize the world monitor-wise. */
        MOVEI 1,.FHSLF          /* Get this process' */
        GPJFN%                  /* .PRIIN and .PRIOU */
        MOVE 3,2                /* Save over coming JSYSi */
        AOJE 2,O7BIT            /* Save a few calls for normal case */
        HLRZ 1,3                /* Get .PRIIN */
        RFBSZ%                  /* byte size */
         JRST I7BIT             /* Probably .CTTRM */
        CAIE 2,7                /* 7-bit? */
         SOS .UIOFL##+1         /* No, don't convert LF */
I7BIT:  HRRZ 1,3                /* Get .PRIOU */
        RFBSZ%                  /* byte size */
         JRST O7BIT             /* Probably .CTTRM */
        CAIE 2,7                /* 7-bit? */
         SOS .UIOFL##+2         /* No, don't convert LF */
O7BIT:
If you SPJFN% to a non-7-bit file you don't want LF -> CR+LF conversion.
-------------------------------------------------------------------------------
Jan Michael Rynning,
Department of Numerical Analysis and Computing Science,
Royal Institute of Technology,
S-100 44 Stockholm,
Sweden.
[email protected]
-------
-------
30-Jun-88 13:43:49-PDT,695;000000000000
Mail-From: KLH created at 30-Jun-88 13:38:29
Date: Thu, 30 Jun 88 13:38:15 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: [Jan Michael Rynning <Jan-Rynning%[email protected]>: Compiler and runtime library fix for KCC.]
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Thanks, I already have the macro fix in, but the redirection fix is
different.  I'll have to think about it to make sure that will usually
do the right thing, and then will apply whatever-it-is to someplace
farther along in the URT.C startup -- not in the C startup.
-------
14-Jul-88 05:23:29-PDT,1218;000000000000
Received: from SIMTEL20.ARPA by SRI-NIC.ARPA with TCP; Thu, 14 Jul 88 05:18:57 PDT
Date: Thu, 14 Jul 1988  06:19 MDT
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: More on debugging (backtracing)

At long last, I now have the contents of Regs 1-17 and the
corresponding SAVEd image of a crashed KCC-compiled program to figure
out how to backtrace through the stack.  I've rummaged upward from the
right-half address in AC 17 (and the left half, too), and I'm at a
loss in trying to make heads or tails out of it all.  I (obviously)
need help from anyone who knows how to do this in their sleep (so it
should only take a few minutes).

Strange stuff: it took several weekends of a volunteer caller manually
repeating the identical steps in many runs before the program would
crash.  When it did crash, the location was identical to the
previously reported crashes.  The logs show the successes (requesting
a particular filename via "uucp" - and I can't see anything "unusual"
about the filename - but the file itself is unusual in that it is very
short - 197 chars)...

--Frank
14-Jul-88 14:38:54-PDT,462;000000000000
Mail-From: KLH created at 14-Jul-88 14:37:30
Date: Thu, 14 Jul 88 14:37:20 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: More on debugging (backtracing)
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

If you want help, how about saying where the source, binary, and
saved-image-with-register-dump is located?
-------
 3-Aug-88 14:32:20-PDT,2552;000000000000
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Wed, 3 Aug 88 14:13:07 PDT
Date: Wed, 3 Aug 1988  17:11 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: Misplaced ADJSP in optimized output from KCC-5

This is running a completely vanilla distribution KCC-5 without any of
the bugfixes you've distributed by via email, so do tell me if you've
already fixed this.

The bug is the ADJSP 17,200 at $1 in the optimized version.  It should
preceed, not follow, the function call.

--Rob

[PHOTO:  Recording initiated  Wed 3-Aug-88 5:04PM]

 MIT TOPS-20 Command Processor 5(312162)-2
XX>ty kccbug.c
#define SIZE	(128)
#define NULL	(0)
int foo(a)
    int *a;
{
    char *b[SIZE];
    if(a != NULL)
	bar(b+SIZE);
    return(1);
}
XX>cc -S kccbug.c
KCC:	kccbug
XX>ty kccbug.fai
	TITLE	kccbug
	.REQUEST C:LIBc.REL
	$$CVER==<2,,2>
	INTERN $$CVER
	OPDEF ADJBP [IBP]
DEFINE %CHRBP(A,M)
<	SETO A,
	ADJBP A,M
>
IFNDEF ERJMP,< OPDEF ERJMP [JUMP 16,] >
OPDEF ERJMPA [ERJMP]
OPDEF	XMOVEI	[SETMI]
	DEFINE IFIW <SETZ >
OPDEF XBLT [020000,,0]
	TWOSEG	400000	
	RELOC	0	
	RELOC	400000	
	DEFINE %%CODE <RELOC>
	DEFINE %%DATA <RELOC>
PURGE IFE,IFN,IFG,IFGE,IFL,IFLE,IFDEF,IFNDEF,IFIDN,IFDIF
foo:
	SKIPN 4,-1(17)
	 JRST $1
	XMOVEI 5,1(17)
	PUSH 17,5
	PUSHJ 17,bar
	ADJSP 17,-1
$1==.
	ADJSP 17,200
	MOVEI 1,1
	ADJSP 17,-200
	POPJ 17,

$$CPKI==0
	INTERN $$CPKI
$$CPKA==0
	INTERN $$CPKA

	LIT
	EXTERN	$$$CPU
	EXTERN	$$$CRT
	INTERN	foo
	EXTERN	bar
	END
XX>cc -S -O= kccbug.c
KCC:	kccbug
XX>ty kccbug.fai
	TITLE	kccbug
	.REQUEST C:LIBc.REL
	$$CVER==<2,,2>
	INTERN $$CVER
	OPDEF ADJBP [IBP]
DEFINE %CHRBP(A,M)
<	SETO A,
	ADJBP A,M
>
IFNDEF ERJMP,< OPDEF ERJMP [JUMP 16,] >
OPDEF ERJMPA [ERJMP]
OPDEF	XMOVEI	[SETMI]
	DEFINE IFIW <SETZ >
OPDEF XBLT [020000,,0]
	TWOSEG	400000	
	RELOC	0	
	RELOC	400000	
	DEFINE %%CODE <RELOC>
	DEFINE %%DATA <RELOC>
PURGE IFE,IFN,IFG,IFGE,IFL,IFLE,IFDEF,IFNDEF,IFIDN,IFDIF
foo:
	ADJSP 17,200
	XMOVEI 3,-201(17)
	MOVE 4,0(3)
	MOVEI 5,0
	CAMN 4,5
	 JRST $1
	XMOVEI 6,-177(17)
	MOVEI 7,200
	ADD 7,6
	PUSH 17,7
	XMOVEI 10,bar
	PUSHJ 17,0(10)
	ADJSP 17,-1
$1==.
	MOVEI 3,1
	MOVE 1,3
	ADJSP 17,-200
	POPJ 17,
	ADJSP 17,-200
	POPJ 17,

$$CPKI==0
	INTERN $$CPKI
$$CPKA==0
	INTERN $$CPKA

	LIT
	EXTERN	$$$CPU
	EXTERN	$$$CRT
	INTERN	foo
	EXTERN	bar
	END
XX>pop

[PHOTO:  Recording terminated  Wed 3-Aug-88 5:05PM]
 3-Aug-88 17:45:34-PDT,437;000000000000
Mail-From: KLH created at  3-Aug-88 17:41:39
Date: Wed, 3 Aug 88 17:41:35 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: Misplaced ADJSP in optimized output from KCC-5
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

OK, fixed.  See the INFO-KCC message about KCC 606 for the source change.
-------
 5-Aug-88 16:40:51-PDT,767;000000000000
Mail-From: KLH created at  5-Aug-88 16:35:22
Date: Fri, 5 Aug 88 16:35:13 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: another KCC bug?
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

  It appears that clearerr doesn't clear the end of file flag.  This is a screw
  if you're doing stdin input for a block of text terminated by CTRL/Z and then
  want to input other cruft.

It turns out that the latest X3J11 dpANS defines clearerr() as clearing both
the error and EOF flags, so you're right, this will be fixed.

Sigh, EOF on TTY input is a tricky thing even with the read/write syscalls.
-------
 5-Aug-88 17:43:38-PDT,1362;000000000000
Mail-From: KLH created at  5-Aug-88 17:40:45
Return-Path: <[email protected]>
Received: from CC.UTAH.EDU by SRI-NIC.ARPA with TCP; Fri, 5 Aug 88 17:36:37 PDT
Received: from ctcp-daemon by CC.UTAH.EDU; Fri, 5 Aug 88 18:35 MDT
Date: Fri 5 Aug 88 18:26:49-MDT
From: Grant Gustafson <[email protected]>
Subject: CRT module in KCC
To: [email protected]
Cc: [email protected]
US-Mail: "Dept. of Math., 113 JWB, U of U, SLC, UT 84112"
Telephone: "(801) 581-6879 or 466-6820 (home)"
Message-ID: <[email protected]>
ReSent-Date: Fri, 5 Aug 88 17:40:43 PDT
ReSent-From: Ken Harrenstien <[email protected]>
ReSent-To: [email protected]
ReSent-Message-ID: <[email protected]>

In 1987, I modified CRT to make a special CRT0.REL which allowed
a KCC program to be restarted. The idea was to KEEP the program
under TOPS-20 and re-enter it a number of times. 

It worked. That was probably KCC-3 (12-may-1987 to 11-Nov-1987).

The new CRT for KCC-5 does not seem to be so easily modified.
At least, I can't do it yet.

Question: Can the old CRT.C from may-1987 be modified to use
with KCC-5? If not, then how do I fix CRT.C to allow KCC programs
to restart?

Grant B. Gustafson, 113 JWB, Math Dept., U of U, SLC, UT 84112
(801) 581-6879 /(801) 466-6820 home.
-------
 5-Aug-88 18:06:03-PDT,1348;000000000001
Mail-From: KLH created at  5-Aug-88 17:56:41
Date: Fri, 5 Aug 88 17:56:36 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: CRT module in KCC
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

There are good reasons why exit() doesn't permit continuation or restarting,
and I suspect you have discovered some of them the hard way.

The primary reason is that C must guarantee the contents of all data
declarations at startup.  Initialized variables must have the values
specified by the programmer, and uninitialized data is given a zero
value.  Lots of code, including the USYS routines of the C library,
depends on this.

If you want to be able to interrupt and then continue a program, you can
use ^C and "continue".  If you want to set up your program so it returns
to the EXEC but can still be continued, use "kill(getpid(), SIGTSTP);"
which in the KCC implementation does a HALTF%.

The main problem with these solutions is that you can't furnish new
command lines (ie a new argv/argc set), but there isn't any way to do
this on Unix.  If you are willing to be unportable then you could invoke
RSCAN% and re-parse the line yourself after returning from the kill().
-------
26-Aug-88 16:10:35-PDT,1918;000000000000
Received: from SUMEX-AIM.Stanford.EDU by SRI-NIC.ARPA with TCP; Fri, 26 Aug 88 16:08:12 PDT
Received: from KSL-1186-4.STANFORD.EDU by SUMEX-AIM.Stanford.EDU with TCP; Fri, 26 Aug 88 16:05:11 PDT
Date: Fri, 26 Aug 88 16:02:16 PDT
From: Mark Crispin <[email protected]>
Subject: malloc suggestion
To: [email protected]
Message-ID: <[email protected]>

Ken -

     Please consider making malloc blocks have trailers as well as headers;
this would be great for catching fencepost errors, e.g. where you malloc n
bytes for a string of size n instead of n+1 (for the trailing null).  I just
nailed a bug of that kind in my application; it was a relatively obscure case
to begin with, it would only have effects 25% of the time (since the string
would have to a multiple of the word size), and most of the time it was
malloc'ing new space.  You'd have to be reusing a freelist block in order to
see the problem.

     The trailer could be just 1 word long, holding (for the benefit of
DDT'ers) a pointer to the first (data) byte of the block.  This wouldn't nail
gross clobberage, of course, but it would get the fencepost errors.

     Also, the error message should indicate the data byte pointer and not the
header pointer.  It is confusing to see a pointer in the error message that
doesn't match the pointer you thought you had.  I scratched my head for a long
while before it occured to me that it was referring to a header, and
consultation with the KCC sources confirmed it.

     It may also be nice to have a library routine which chases through free
storage and verifies that all free and in-use blocks are OK.  Of course, that
would require some sort of linking of in-use blocks, which may not be all that
bad an idea to help a programmer identify forgotten malloc blocks and where
they may have come from.

-- Mark --

 1-Sep-88 13:19:18-PDT,857;000000000011
Received: from SCIENCE.UTAH.EDU by SRI-NIC.ARPA with TCP; Thu, 1 Sep 88 12:52:56 PDT
Date: Thu 1 Sep 88 13:52:18-MDT
From: "Nelson H.F. Beebe" <[email protected]>
Subject: Re: malloc suggestion
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
X-US-Mail: "Center for Scientific Computing, South Physics, University of Utah, Salt Lake City, UT 84112"
X-Telephone: (801) 581-5254
Message-ID: <[email protected]>

I added trailers to malloc() blocks last spring, but I guess it hasn't
made it into the official distribution channels.  Anyone who wants to
pick up the code can find it in C:MALLOC-MAIL.TXT (a TOPS-20 mail file)
on SCIENCE.UTAH.EDU via ANONYMOUS FTP; I'll remail it if FTP fails for
you.
-------
19-Sep-88 11:52:38-PDT,1487;000000000000
Received: from uunet.UU.NET by SRI-NIC.ARPA with TCP; Mon, 19 Sep 88 11:47:05 PDT
Received: from enea.UUCP by uunet.UU.NET (5.59/1.14) with UUCP 
	id AA22401; Mon, 19 Sep 88 14:47:58 EDT
Received: from kth.se by enea.se (5.57++/1.84)
	id AA22896; Mon, 19 Sep 88 19:53:00 +0200 (MET)
Received: from VERA.NADA.KTH.SE by kth.se (5.57+IDA+KTH/3.0)
	id AA01704; Mon, 19 Sep 88 19:51:56 +0200
Date: Mon 19 Sep 88 19:53:50
From: Jan Michael Rynning <[email protected]>
Subject: SIZEF% - old bug killed!
To: [email protected]
Cc: [email protected]
Organization: Royal Institute of Technology, Stockholm, Sweden.
Address: NADA, KTH, S-100 44 Stockholm, Sweden.
Telephone: +46-8-7906288
Message-Id: <[email protected]>

Situation:
  Have file with one bytesize (e.g. 36).
  Want to read with different bytesize (e.g. 8).
Attempt:
  Open with "rb8".
Problem:
  Positioning relative to the end of the file doesn't work.
Cause:
  LSEEK does a SIZEF% to get length. Gets length in 36-bit words, which is
  1/4 of length in 8-bit bytes. Positions relative to one quarter down the
  file, not relative to the end.
Result:
  Disaster. Program screws up, and fills entire disk structure.
Solution:
  Rewrite LSEEK (and STAT while I was at it) to compute correct length. Use
  the same algorithm as NFBSZ (FILEJS.MAC on TENEX/JSYSF.MAC on TOPS-20). I
  send you the rewritten LSEEK.C and STAT.C as separate mail messages.
-------
19-Sep-88 11:53:26-PDT,2596;000000000000
Received: from uunet.UU.NET ([192.12.141.129]) by SRI-NIC.ARPA with TCP; Mon, 19 Sep 88 11:47:21 PDT
Received: from enea.UUCP by uunet.UU.NET (5.59/1.14) with UUCP 
	id AA22417; Mon, 19 Sep 88 14:48:06 EDT
Received: from kth.se by enea.se (5.57++/1.84)
	id AA22952; Mon, 19 Sep 88 19:55:30 +0200 (MET)
Received: from VERA.NADA.KTH.SE by kth.se (5.57+IDA+KTH/3.0)
	id AA01716; Mon, 19 Sep 88 19:54:25 +0200
Date: Mon 19 Sep 88 19:56:22
From: Jan Michael Rynning <[email protected]>
Subject: LSEEK.C (see "SIZEF% - old bug killed!" message)
To: [email protected]
Organization: Royal Institute of Technology, Stockholm, Sweden.
Address: NADA, KTH, S-100 44 Stockholm, Sweden.
Telephone: +46-8-7906288
Message-Id: <[email protected]>

/* SS:<KCC-5.LIB.USYS>LSEEK.C.33 19-Sep-88 15:51:44, Edit by JAN-RYNNING
 * _nfbsz correct file length for 10X+T20 instead of SIZEF%
 *
 *	LSEEK - move read/write pointer
 *	TELL - (obsolete) get read/write pointer
 *
 *	Copyright (C) 1986 by Ian Macky, SRI International
 *
 */

#include "c-env.h"
#include "sys/usysio.h"
#include "sys/usysig.h"
#include "sys/file.h"	/* Defines L_ flag values */
#include "errno.h"
#if SYS_T20+SYS_10X
#include "jsys.h"
#endif

long
lseek(fd, offset, whence)
int fd, whence;
long offset;
{
    int ufx;
    long ret;

#if SYS_T20+SYS_10X
    int arg_block[5], fdb[2];
    extern int _nfbsz();
    USYS_BEG();

    if (fd < 0 || fd >= OPEN_MAX || !(ufx = _uioufx[fd]))
	USYS_RETERR(EBADF);

    switch (whence) {
	case L_SET:
	    arg_block[2] = offset;
	    break;
	case L_INCR:
	    if (!offset) {		/* efficiency hack */
		ret = _uiopos[ufx];
		USYS_RET(ret);
	    }
	    arg_block[2] = _uiopos[ufx] + offset;
	    break;
	case L_XTND:
	    arg_block[1] = _uioch[ufx];
	    arg_block[2] = (2<<18) | _FBBYV;
	    arg_block[3] = (int) fdb;
	    if (!jsys(GTFDB, arg_block))
		USYS_RETERR(EBADF);
	    arg_block[2] = _nfbsz(_uiobsize[ufx], (fdb[0]>>24)&077, fdb[1]) +
		offset;
	    break;
	default:
	    USYS_RETERR(EINVAL);
    }
    if (arg_block[2] < 0)
	USYS_RETERR(EINVAL);

    arg_block[1] = _uioch[ufx];		/* JFN */
    if (!jsys(SFPTR, arg_block))
	USYS_RETERR(EBADF);		/* Set the file pointer */
    _uiocnt[ufx] = _uioeof[ufx] = 0;	/* force grabbing of a new bufferful */
    ret = _uiopos[ufx] = arg_block[2];	/* return the new position */
    USYS_RET(ret);
#else
#error lseek() not supported for this system.
#endif
}

long
tell(fd)
int fd;
{
    return lseek(fd, 0L, L_INCR);
}
-------
19-Sep-88 11:53:40-PDT,9661;000000000000
Received: from uunet.UU.NET by SRI-NIC.ARPA with TCP; Mon, 19 Sep 88 11:47:52 PDT
Received: from enea.UUCP by uunet.UU.NET (5.59/1.14) with UUCP 
	id AA22435; Mon, 19 Sep 88 14:48:21 EDT
Received: from kth.se by enea.se (5.57++/1.84)
	id AA23077; Mon, 19 Sep 88 19:59:56 +0200 (MET)
Received: from VERA.NADA.KTH.SE by kth.se (5.57+IDA+KTH/3.0)
	id AA01733; Mon, 19 Sep 88 19:58:39 +0200
Date: Mon 19 Sep 88 20:00:32
From: Jan Michael Rynning <[email protected]>
Subject: STAT.C (see "SIZEF% - old bug killed!" message)
To: [email protected]
Organization: Royal Institute of Technology, Stockholm, Sweden.
Address: NADA, KTH, S-100 44 Stockholm, Sweden.
Telephone: +46-8-7906288
Message-Id: <[email protected]>

/* SS:<KCC-5.LIB.USYS>STAT.C.142 19-Sep-88 15:27:35, Edit by JAN-RYNNING
   _nfbsz correct file length for 10X+T20
   [SRI-NIC]SS:<C.LIB.UIO>STAT.C.76, 24-Aug-86 12:23:30, Edit by IAN
   xstat extended stat for T20
   [SRI-NIC]SS:<C.LIB.UIO>STAT.C.42,  3-Jun-86 14:37:53, Edit by IAN
   updated etc
   <KCC.LIB>STAT.C.35, 29-Aug-85 11:23:49, Edit by WHP4
   restructure slightly so fstat() uses fds, not jfns */

/*
** stat(name, buf)
** char *name;
** struct stat *buf;
**
** Greg Satz / Stanford University / 12-Sep-84
** TENEX additions by Ken Harrenstien, SRI 1-Jun-85
*/

#include "c-env.h"
#include "errno.h"
#include "sys/types.h"
#include "sys/file.h"
#include "sys/usysio.h"
#include "sys/usysig.h"
#include "sys/stat.h"
#if SYS_T20+SYS_10X
#include "jsys.h"
#include "sys/time.h"	/* For tadl_to_utime() to convert file times */

extern void _rljfn();
extern int _gtjfn();
static int _stat(), _xstat();
static int t2u_pro(), _gdsts(), _gfust();
#endif

/*
 *	stat(name, buf)
 */

int stat(name, buf)
char *name;
struct stat *buf;
{
#if SYS_T20+SYS_10X
    int jfn, i;

    USYS_BEG();
    if ((jfn = _gtjfn(name, O_RDONLY)) == 0)
	USYS_RETERR(ENOENT);
    i = _stat(jfn, buf, 0);
    _rljfn(jfn);
    USYS_RET(i);
#else /* T20+10X */
#error stat() not supported for this system.
#endif /* Not T20+10X */
}

int xstat(name, buf)
char *name;
struct xstat *buf;
{
#if SYS_T20+SYS_10X
    int jfn, i;

    if ((jfn = _gtjfn(name, O_RDONLY)) == 0)
	USYS_RETERR(ENOENT);
    i = _xstat(jfn, buf, 0);
    _rljfn(jfn);
    USYS_RET(i);
#else /* T20+10X */
#error xstat() not supported for this system.
#endif /* Not T20+10X */
}

int fstat(fd, buf)
int fd;
struct stat *buf;
{
    int ufx;

    USYS_BEG();
    if (fd < 0 || fd >= OPEN_MAX || !(ufx = _uioufx[fd]))
	USYS_RETERR(EBADF);
#if SYS_T20+SYS_10X
    USYS_RETVOLATILE(_stat(_uioch[ufx], buf, ufx));
#else /* T20+10X */
#error fstat() not supported for this system.
#endif /* not T20+10X */
}

int xfstat(fd, buf)
int fd;
struct xstat *buf;
{
    int ufx;

    if (fd < 0 || fd >= OPEN_MAX || !(ufx = _uioufx[fd]))
	USYS_RETERR(EBADF);
#if SYS_T20+SYS_10X
    USYS_RETVOLATILE(_xstat(_uioch[ufx], buf, ufx));
#else
#error xfstat() not supported for this system.
#endif
}
/*
 *	_stat(jfn, buf, ufx) - worker routine for stat() and fstat()
 *	_xstat(jfn, xbuf, ufx) - do above plus device dependent stuff
 */

static int
_stat(jfn, buf, ufx)
int jfn, ufx;
struct stat *buf;
{
#if SYS_T20+SYS_10X
    int i, fdb[_FBLEN], bytsiz;
    char name[FILEPART_SIZE];
    unsigned protection;
    int acs[5];

    if (jfn == _PRIIN) _get_pio(&jfn, 0);	/* in case redirected */
    else if (jfn == _PRIOU) _get_pio(0, &jfn);

    acs[1] = jfn;
    acs[2] = _FBLEN << 18;			/* get the whole FDB */
    acs[3] = (int) fdb;
    if (!jsys(GTFDB, acs))
	return -1;

    buf->st_dev = _dvtype(jfn);
    buf->st_ino = fdb[_FBADR];			/* disk address */
    buf->st_mode = 0;
    protection = fdb[_FBCTL];
    buf->st_mode |= ((protection & FB_DIR) ? S_IFDIR : S_IFREG);
    protection = fdb[_FBPRT];			/* protection */
    i = (protection & T20_OWNER_MASK) >> T20_OWNER_OFFSET;
    buf->st_mode |= (t2u_pro(i) >> UNIX_OWNER_OFFSET);
    i = (protection & T20_GROUP_MASK) >> T20_GROUP_OFFSET;
    buf->st_mode |= (t2u_pro(i) >> UNIX_GROUP_OFFSET);
    i = (protection & T20_WORLD_MASK) >> T20_WORLD_OFFSET;
    buf->st_mode |= (t2u_pro(i) >> UNIX_WORLD_OFFSET);
    buf->st_nlink = 1;				/* can it be anything else? */
#if SYS_10X
    i = fdb[_FBUSE];
    buf->st_uid = ((unsigned) i >> 18);		/* Get LH (directory #) */
#endif
#if SYS_T20
    _gfust(jfn, _GFAUT, name);
    buf->st_uid = _rcusr(name);
#endif
    buf->st_gid = 0;			/* for now */
    buf->st_rdev = 0;			/* no major/minor devices on tops */
    buf->st_atime = tadl_to_utime(fdb[_FBREF]);
    buf->st_mtime = tadl_to_utime(fdb[_FBWRT]);
    buf->st_ctime = tadl_to_utime(fdb[_FBCRE]);

    /* Set size vars. */
    /* TOPS-20 has several stupid screws with respect to newly created files,
    ** or files being updated.  Newly created files don't actually exist until
    ** they have been CLOSF%'d, so the FDB size information is all 0.  open()
    ** attempts to circumvent this by doing a quick CLOSF/OPENF; however, then
    ** the update problem comes up, because TOPS-20 doesn't update the FDB
    ** size info until a CLOSF% is done after writing!!  If we are writing the
    ** file ourselves, we look at our own info to see what's up.
    */
    buf->st_size = fdb[_FBSIZ];		/* First try what FDB has */
    bytsiz = (fdb[_FBBYV]>>24)&077;	/* Get FDB bytesize */
    if (bytsiz == 0)			/* Monitor assumes 0 means 36 */
	bytsiz = 36;
    buf->st_blksize =(36/bytsiz) * 512;	/* # bytes in page */
    buf->st_blocks = fdb[_FBBYV]&RH;	/* # pages (blocks) in file */

    if (ufx) {				/* Have it open ourselves? */
	if (bytsiz != _uiobsize[ufx]) {	/* Yes, check bytesize info */
	    /* Update length, # bytes in page, and bytesize */
	    buf->st_size = _nfbsz(_uiobsize[ufx], bytsiz, buf->st_size);
	    buf->st_blksize = (36/_uiobsize[ufx]) * 512;
	    bytsiz = _uiobsize[ufx];
	}
	if (buf->st_size < _uiopos[ufx])	/* If our len info is better */
	    buf->st_size = _uiopos[ufx];	/* update it! */

	i = (buf->st_size + buf->st_blksize-1) / buf->st_blksize;
	if (buf->st_blocks < i)			/* If our page info better */
	    buf->st_blocks = i;			/* # pages (blocks) in file */
    }

    return 0;				/* success */
#else /* T20+10X */
    return -1;				/* Not implemented elsewhere yet */
#endif /* Not T20+10X */
}

static int _xstat(jfn, buf, ufx)
int jfn, ufx;
struct xstat *buf;
{
#if SYS_T20+SYS_10X
    int fbbyv, ablock[5];

    if (jfn == _PRIIN) _get_pio(&jfn, 0);	/* in case redirected */
    else if (jfn == _PRIOU) _get_pio(0, &jfn);
    if (_stat(jfn, &buf->st, ufx))		/* get primary stuff */
	return -1;				/* failed! */
    switch (buf->st.st_dev) {			/* device-dependant stuff */
	case ST_DEV_DSK:
	    buf->xst_version = _gtfdb(jfn, _FBGEN) >> 18;
	    fbbyv = _gtfdb(jfn, _FBBYV);
	    buf->xst_pagcnt = fbbyv & RH;
	    buf->xst_bytsiz = (fbbyv << FBBSZ_S) & FBBSZ_M;
	    break;
	case ST_DEV_TCP:
	    _gdsts(jfn, &buf->xst_state, &buf->xst_fhost, &buf->xst_fport);
	    break;
    }
    return 0;
#else
    return -1;
#endif
}

#if SYS_T20+SYS_10X
/*
 *	get primary JFNs for ourself
 */

int _get_pio(i, o)
int *i, *o;
{
    int ac[5];

    ac[1] = _FHSLF;		/* "Self" process handle */
    if (jsys(GPJFN, ac)) {
	if (i) *i = ((unsigned) ac[2]) >> 18;
	if (o) *o = ac[2] & RH;
	return 1;
    } else return 0;
}

/*
 *	Takes TOPS-20 protections right justified and returns Unix protections
 *	right justified.
 */

static int t2u_pro(prot)
unsigned prot;
{
    int i = 0;

    if (prot & FP_READ)		i |= S_IREAD;
    if (prot & FP_WRITE)	i |= S_IWRITE;
    if (prot & FP_EXECUTE)	i |= S_IEXEC;
    return i;
}

/*
 *	_GTFDB() - read (and return) a word from a file's fdb
 *	this routine is exported, don't make it static!
 */

int _gtfdb(jfn, word)
int jfn, word;
{
    int temp, arg_block[5];

    arg_block[1] = jfn;
    arg_block[2] = (1 << 18) + word;
    arg_block[3] = 3;				/* put the value in AC3 */
    return (jsys(GTFDB, arg_block)) ? arg_block[3] : 0;
}

/*
 *	_gdsts(jfn, a, b, c) - get device status stuff.
 *	int jfn, *a, *b, *c;
 *
 *		Stores the ACs returned by GDSTS%
 */

static int _gdsts(jfn, a, b, c)
int jfn, *a, *b, *c;
{
    int ablock[5];

    ablock[1] = jfn;
    if (!jsys(GDSTS, ablock)) return 0;
    if (a) *a = ablock[2];
    if (b) *b = ablock[3];
    if (c) *c = ablock[4];
    return 1;
}

/*
 *	Get device characteristics
 */

int _dvtype(jfn)
int jfn;
{
    unsigned ablock[5];

    ablock[1] = jfn;
    return (jsys(DVCHR, ablock)) ? ((ablock[2] >> DV_TYP_S) & DV_TYP_M) : -1;
}

/*
 *	Get file user
 */

static int _gfust(jfn, func, name)
int jfn, func;
char *name;
{
    int ablock[5];

    ablock[1] = (func << 18) | jfn;
    ablock[2] = (int)(name-1);
    return jsys(GFUST, ablock);
}

/*
 *	Return username number for given user name
 */

int _rcusr(name)
char *name;
{
    int ablock[5];

    ablock[1] = RC_EMO;
    ablock[2] = (int) (name - 1);
    if (!jsys(RCUSR, ablock) || (ablock[1] & RC_NOM))  /* jsys error */
	return -1;
    return ablock[3];
}

/*
 *	Return correct file length
 */

int _nfbsz(ourbsz, filbsz, fillen)
int ourbsz, filbsz, fillen;
{
    int ourlen, ourbpw, filbpw;

    ourbpw = ourbsz ? (36/ourbsz) : 1;
    filbpw = filbsz ? (36/filbsz) : 1;
    ourlen = (fillen * ourbpw + filbpw-1) / filbpw;
    return ourlen;
}
#endif /* T20+10X */
-------
20-Sep-88 03:53:03-PDT,2914;000000000000
Received: from uunet.UU.NET by SRI-NIC.ARPA with TCP; Tue, 20 Sep 88 03:47:26 PDT
Received: from enea.UUCP by uunet.UU.NET (5.59/1.14) with UUCP 
	id AA26272; Tue, 20 Sep 88 06:47:13 EDT
Received: from kth.se by enea.se (5.57++/1.84)
	id AA09839; Tue, 20 Sep 88 11:53:57 +0200 (MET)
Received: from VERA.NADA.KTH.SE by kth.se (5.57+IDA+KTH/3.0)
	id AA10548; Tue, 20 Sep 88 11:52:36 +0200
Date: Tue 20 Sep 88 11:54:22
From: Jan Michael Rynning <[email protected]>
Subject: Even better LSEEK.C
To: [email protected]
Organization: Royal Institute of Technology, Stockholm, Sweden.
Address: NADA, KTH, S-100 44 Stockholm, Sweden.
Telephone: +46-8-7906288
Message-Id: <[email protected]>

I had forgotten one thing in the LSEEK.C I sent you: just like in STAT.C,
_uiopos[ufx] might be beyond where the monitor thinks the file ends, and
if it is, that value should be used instead. Here's an even better LSEEK.C:

/* SS:<KCC-5.LIB.USYS>LSEEK.C.33 19-Sep-88 15:51:44, Edit by JAN-RYNNING
 * _nfbsz correct file length for 10X+T20 instead of SIZEF%
 *
 *	LSEEK - move read/write pointer
 *	TELL - (obsolete) get read/write pointer
 *
 *	Copyright (C) 1986 by Ian Macky, SRI International
 *
 */

#include "c-env.h"
#include "sys/usysio.h"
#include "sys/usysig.h"
#include "sys/file.h"	/* Defines L_ flag values */
#include "errno.h"
#if SYS_T20+SYS_10X
#include "jsys.h"
#endif

long
lseek(fd, offset, whence)
int fd, whence;
long offset;
{
    int ufx;
    long ret;

#if SYS_T20+SYS_10X
    int arg_block[5], fdb[2];
    extern int _nfbsz();
    USYS_BEG();

    if (fd < 0 || fd >= OPEN_MAX || !(ufx = _uioufx[fd]))
	USYS_RETERR(EBADF);

    switch (whence) {
	case L_SET:
	    arg_block[2] = offset;
	    break;
	case L_INCR:
	    if (!offset) {		/* efficiency hack */
		ret = _uiopos[ufx];
		USYS_RET(ret);
	    }
	    arg_block[2] = _uiopos[ufx] + offset;
	    break;
	case L_XTND:
	    arg_block[1] = _uioch[ufx];
	    arg_block[2] = (2<<18) | _FBBYV;
	    arg_block[3] = (int) fdb;
	    if (!jsys(GTFDB, arg_block))
		USYS_RETERR(EBADF);
	    arg_block[2] = _nfbsz(_uiobsize[ufx], (fdb[0]>>24)&077, fdb[1]);
	    if (arg_block[2] < _uiopos[ufx])	/* If our len info is better */
		arg_block[2] = _uiopos[ufx];	/* update it! */
	    arg_block[2] += offset;
	    break;
	default:
	    USYS_RETERR(EINVAL);
    }
    if (arg_block[2] < 0)
	USYS_RETERR(EINVAL);

    arg_block[1] = _uioch[ufx];		/* JFN */
    if (!jsys(SFPTR, arg_block))
	USYS_RETERR(EBADF);		/* Set the file pointer */
    _uiocnt[ufx] = _uioeof[ufx] = 0;	/* force grabbing of a new bufferful */
    ret = _uiopos[ufx] = arg_block[2];	/* return the new position */
    USYS_RET(ret);
#else
#error lseek() not supported for this system.
#endif
}

long
tell(fd)
int fd;
{
    return lseek(fd, 0L, L_INCR);
}
-------
20-Sep-88 16:15:29-PDT,547;000000000000
Mail-From: KLH created at 20-Sep-88 15:30:55
Date: Tue, 20 Sep 88 15:30:35 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: SIZEF% - old bug killed!
To: [email protected], [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Thanks for the fix.  The source files LSEEK.C and STAT.C have changed somewhat
since the versions you have, but your fix is still applicable and has been
integrated.
-------
23-Sep-88 18:12:21-PDT,3119;000000000000
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Fri, 23 Sep 88 18:08:37 PDT
Date: Fri, 23 Sep 1988  21:08 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: stdio bug [ftell() or scanf(), I think]

The following bug cropped up when I was trying to write a simple
interpreter for a network test program; the standard input to the
program is a script specifying which of several test operations to do,
in what order, and how many times.  Three of the commands to this
interpreter are as follows:

'#' followed by a decimal number, to set the "counter".

'{' mark the current position in the script (as reported by ftell())
as the begining of a loop.

'}' subtract one from the "counter" and fseek() back to the position
recorded by '{' if the result is positive.

Ie, I was attemping to implement a simple FOR loop in my interpeter.

Here is a photo of a stripped down version of the interpreter with
just those three commands and no action routines, so that you can see
how it loses.  It appears that ftell() reports a bad position
initially, but after a few iterations ftell() reports the true
character position and the loop works as intended.

--Rob

[PHOTO:  Recording initiated  Fri 23-Sep-88 8:56PM]

 MIT TOPS-20 Command Processor 5(312162)-2
XX>orig type telbug.c,telbug.input
 TELBUG.C.8

#include <stdio.h>
main()
{
    int c, pos = 0, ntimes = 0;
    while((c = getchar()) != EOF)
	switch(c) {
	    case '#':
		scanf(" %d", &ntimes);
		printf("ntimes = %d, c = '%c', pos = %d\n", ntimes, c, pos);
		continue;
	    case '{':
		pos = ftell(stdin);
		printf("ntimes = %d, c = '%c', pos = %d\n", ntimes, c, pos);
		continue;
	    case '}':
		printf("ntimes = %d, c = '%c', pos = %d\n", ntimes, c, pos);
		if(--ntimes > 0)
		    fseek(stdin,pos,0);
		continue;
	    default:
#if 0
		printf("ntimes = %d, c = '%c', pos = %d\n", ntimes, c, pos);
#endif
		continue;
	}
}

 TELBUG.INPUT.2

[XX.LCS.MIT.EDU]XX:<SRA.WORK4>TELBUG.INPUT.2, 23-Sep-88 20:53:11, Edit by SRA

Everything in this file will be ignored except for three characters
that are used for loop control and the number following one of them.
I don't know why reading a number should screw things up the way it
does, but this bug appear to go away without the scanf() code that
does it.

# 10				;set counter to ten
{				;start looping
}				;stop looping
XX>
XX>cc telbug.c
KCC:	telbug
MACRO:	telbug

EXIT
LINK:	Loading
XX>telbug <telbug.input
ntimes = 10, c = '#', pos = 0
ntimes = 10, c = '{', pos = 390
ntimes = 10, c = '}', pos = 390
ntimes = 9, c = '{', pos = 398
ntimes = 9, c = '}', pos = 398
ntimes = 8, c = '{', pos = 399
ntimes = 8, c = '}', pos = 399
ntimes = 7, c = '}', pos = 399
ntimes = 6, c = '}', pos = 399
ntimes = 5, c = '}', pos = 399
ntimes = 4, c = '}', pos = 399
ntimes = 3, c = '}', pos = 399
ntimes = 2, c = '}', pos = 399
ntimes = 1, c = '}', pos = 399
XX>pop

[PHOTO:  Recording terminated  Fri 23-Sep-88 8:57PM]
23-Sep-88 18:22:12-PDT,525;000000000000
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Fri, 23 Sep 88 18:17:18 PDT
Date: Fri, 23 Sep 1988  21:17 EDT
Message-ID: <[email protected]>
From: Rob Austein <[email protected]>
To:   [email protected]
Subject: correction

A varient on the previous test shows that the scanf() is irrelevant,
if you change the initial value of ntimes to 10 and remove the '#'
case from the switch() it still loses the same way.  So presumably the
bug really is ftell().

Sorry for the confusion.
 6-Oct-88 10:42:31-PDT,1342;000000000000
Received: from SIMTEL20.ARMY.MIL by SRI-NIC.ARPA with TCP; Thu, 6 Oct 88 10:36:20 PDT
Date: Thu, 6 Oct 1988  11:35 MDT
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: MLIST no longer compiles

My MLIST.C program, as distributed with the MM/MMAILR package, no
longer compiles to completion.  Source is in PS:<MM> here.

--Frank
--------------------

[PHOTO:  Recording initiated  Thu 6-Oct-88 11:23AM]

$def unv:sys:
$cc mlist
KCC:	mlist
"mlist.c", line 321: Macro nesting depth exceeded
       (_xfork+32, p.1 l.321): z 2,2  movem 2,PC   %CHRBP 1,-2(17)  ; Get RSCAN

"mlist.c", line 321: Macro nesting depth exceeded
       (_xfork+32, p.1 l.321): z 2,2  movem 2,PC   %CHRBP 1,-2(17)  ; Get RSCAN

"mlist.c", line 321: Macro nesting depth exceeded
       (_xfork+32, p.1 l.321): z 2,2  movem 2,PC   %CHRBP 1,-2(17)  ; Get RSCAN

"mlist.c", line 321: Macro nesting depth exceeded
       (_xfork+32, p.1 l.321): z 2,2  movem 2,PC   %CHRBP 1,-2(17)  ; Get RSCAN

"mlist.c", line 321: Macro nesting depth exceeded
       (_xfork+32, p.1 l.321): z 2,2  movem 2,PC   %CHRBP 1,-2(17)  ; Get RSCAN

?KCC - 5 error(s) detected
$pop

[PHOTO:  Recording terminated Thu 6-Oct-88 11:24AM]
 7-Oct-88 11:21:58-PDT,596;000000000000
Received: from SIMTEL20.ARMY.MIL by SRI-NIC.ARPA with TCP; Fri, 7 Oct 88 10:47:47 PDT
Date: Fri, 7 Oct 1988  08:55 MDT
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   Rob Austein <[email protected]>
Cc:   [email protected], [email protected]
Subject: MLIST no longer compiles
In-reply-to: Msg of 7 Oct 1988  07:42-MDT from Rob Austein <SRA at XX.LCS.MIT.EDU>

Rob,

That worked, and also my fix to MLIST solved the BABYL problem we
discussed.  Maybe I should have read the documentation?

Thanks,
Frank
 7-Oct-88 11:25:03-PDT,511;000000000000
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Fri, 7 Oct 88 10:59:21 PDT
Date: Fri 7 Oct 88 09:42:32-EDT
From: Rob Austein <[email protected]>
Subject: Re: MLIST no longer compiles
To: [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Frank,

If you change all the comments in your #asm code from "; ... " syntax
to "/* ... */" syntax your problem will go away.

--Rob
-------
 7-Oct-88 16:34:40-PDT,1347;000000000000
Received: from SCIENCE.UTAH.EDU by SRI-NIC.ARPA with TCP; Fri, 7 Oct 88 16:11:24 PDT
Date: Fri 7 Oct 88 17:10:27-MDT
From: "Nelson H.F. Beebe" <[email protected]>
Subject: Data initialization bug
To: [email protected]
cc: [email protected]
X-US-Mail: "Center for Scientific Computing, South Physics, University of Utah, Salt Lake City, UT 84112"
X-Telephone: (801) 581-5254
Message-ID: <[email protected]>

The file foo.c:
       struct {float x;float y;} tb[] = {
        {1.0e+009, 1.1e-001},
        {45435435, 34545434}
        };
gives
$kcc -c foo.c
KCC:    foo
"foo.c", line 2: Bad initializer list syntax
       (p.1 l.2):        struct {float x;float y;} tb[] = {
      {1.0e+009,

?KCC - 1 error(s) detected
Changing 009 to 9 and 001 to 1 gives foo2.c:

       struct {float x;float y;} tb[] = {
        {1.0e+9, 1.1e-1},
        {45435435, 34545434}
        };

$kcc -c foo2.c
KCC:    foo2
<BEEBE>FOO2.PRE.1
<BEEBE>FOO2.FAI.1
FAIL:  foo2
$

and removes the compiler error.  foo.c compiles fine on Sun
Unix cc.

The compiler version is 608:

$v sys:kcc.exe

   FES:<KCC-5>
 KCC.EXE.607;P777752      171 87552(36)   4-Aug-88 20:27:41 BEEBE     
      .608;P777752        171 87552(36)  31-Aug-88 18:51:10 BEEBE     

 Total of 342 pages in 2 files
-------
 7-Oct-88 17:01:08-PDT,14466;000000000000
Received: from SCIENCE.UTAH.EDU by SRI-NIC.ARPA with TCP; Fri, 7 Oct 88 16:55:48 PDT
Date: Fri 7 Oct 88 17:30:05-MDT
From: "Nelson H.F. Beebe" <[email protected]>
Subject: Erroneous %w.de floating-point output
To: [email protected]
cc: [email protected]
X-US-Mail: "Center for Scientific Computing, South Physics, University of Utah, Salt Lake City, UT 84112"
X-Telephone: (801) 581-5254
Message-ID: <[email protected]>

KCC 608 has erroneous floating-point output on a %w.de
format -- 2 digits appear before the decimal point in many
cases with float data; output with double data is correct.

Just in case anyone ever flippantly thought floating-point
programming was easy....  Comparisons with PCC-20 and Sun OS
4.0 cc are included, just to show that others have trouble too.

Here is an annotated PHOTO log:

[PHOTO:  Recording initiated  Fri 7-Oct-88 5:14PM]

 TOPS-20 Command processor 5(712)
@v sys:kcc.exe.0

   FES:<KCC-5>
 KCC.EXE.608;P777752      171 87552(36)  31-Aug-88 18:51:10 BEEBE     

Consider the following:

@type t.c
----------------
APS:<BEEBE>T.C.5
----------------

#include <stdio.h>



float x[] = {1.0e-37, 1.0e-36, 1.0e-35, 1.0e-34, 1.0e-33,
1.0e-32, 1.0e-31, 1.0e-30, 1.0e-29, 1.0e-28, 1.0e-27,
1.0e-26, 1.0e-25, 1.0e-24, 1.0e-23, 1.0e-22, 1.0e-21,
1.0e-20, 1.0e-19, 1.0e-18, 1.0e-17, 1.0e-16, 1.0e-15,
1.0e-14, 1.0e-13, 1.0e-12, 1.0e-11, 1.0e-10, 1.0e-9, 1.0e-8,
1.0e-7, 1.0e-6, 1.0e-5, 1.0e-4, 1.0e-3, 1.0e-2, 1.0e-1,
1.0e0, 1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5, 1.0e6, 1.0e7,
1.0e8, 1.0e9, 1.0e10, 1.0e11, 1.0e12, 1.0e13, 1.0e14,
1.0e15, 1.0e16, 1.0e17, 1.0e18, 1.0e19, 1.0e20, 1.0e21,
1.0e22, 1.0e23, 1.0e24, 1.0e25, 1.0e26, 1.0e27, 1.0e28,
1.0e29, 1.0e30, 1.0e31, 1.0e32, 1.0e33, 1.0e34, 1.0e35,
1.0e36, 1.0e37, 1.0e38};

double y[] = {1.0e-37, 1.0e-36, 1.0e-35, 1.0e-34, 1.0e-33,
1.0e-32, 1.0e-31, 1.0e-30, 1.0e-29, 1.0e-28, 1.0e-27,
1.0e-26, 1.0e-25, 1.0e-24, 1.0e-23, 1.0e-22, 1.0e-21,
1.0e-20, 1.0e-19, 1.0e-18, 1.0e-17, 1.0e-16, 1.0e-15,
1.0e-14, 1.0e-13, 1.0e-12, 1.0e-11, 1.0e-10, 1.0e-9, 1.0e-8,
1.0e-7, 1.0e-6, 1.0e-5, 1.0e-4, 1.0e-3, 1.0e-2, 1.0e-1,
1.0e0, 1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5, 1.0e6, 1.0e7,
1.0e8, 1.0e9, 1.0e10, 1.0e11, 1.0e12, 1.0e13, 1.0e14,
1.0e15, 1.0e16, 1.0e17, 1.0e18, 1.0e19, 1.0e20, 1.0e21,
1.0e22, 1.0e23, 1.0e24, 1.0e25, 1.0e26, 1.0e27, 1.0e28,
1.0e29, 1.0e30, 1.0e31, 1.0e32, 1.0e33, 1.0e34, 1.0e35,
1.0e36, 1.0e37, 1.0e38};


main()
{
	int k;
	for (k = 0; k < sizeof(x)/sizeof(x[0]); ++k)
		printf("%16.6e %30.17e\n", x[k], y[k]);
}
@kcc t.c
KCC:	t
<BEEBE>T.PRE.1
<BEEBE>T.FAI.1
FAIL:  t
LINK:	Loading
@t.exe
   10.000000e-38        1.00000000000000000e-37
   10.000000e-37        1.00000000000000000e-36
   10.000000e-36        1.00000000000000000e-35
   10.000000e-35        1.00000000000000000e-34
   10.000000e-34        1.00000000000000000e-33
   10.000000e-33        1.00000000000000000e-32
   10.000000e-32        1.00000000000000000e-31
   10.000000e-31        1.00000000000000000e-30
   10.000000e-30        1.00000000000000000e-29
   10.000000e-29        1.00000000000000000e-28
   10.000000e-28        1.00000000000000000e-27
   10.000000e-27        1.00000000000000000e-26
   10.000000e-26        1.00000000000000000e-25
   10.000000e-25        1.00000000000000000e-24
   10.000000e-24        1.00000000000000000e-23
   10.000000e-23        1.00000000000000000e-22
   10.000000e-22        1.00000000000000000e-21
   10.000000e-21        1.00000000000000000e-20
   10.000000e-20        1.00000000000000000e-19
   10.000000e-19        1.00000000000000000e-18
   10.000000e-18        1.00000000000000000e-17
   10.000000e-17        1.00000000000000000e-16
   10.000000e-16        1.00000000000000000e-15
   10.000000e-15        1.00000000000000000e-14
   10.000000e-14        1.00000000000000000e-13
   10.000000e-13        1.00000000000000000e-12
   10.000000e-12        1.00000000000000000e-11
   10.000000e-11        1.00000000000000000e-10
   10.000000e-10        1.00000000000000000e-09
   10.000000e-09        1.00000000000000000e-08
   10.000000e-08        1.00000000000000000e-07
   10.000000e-07        1.00000000000000000e-06
   10.000000e-06        1.00000000000000000e-05
   10.000000e-05        1.00000000000000000e-04
   10.000000e-04        1.00000000000000000e-03
   10.000000e-03        1.00000000000000000e-02
   10.000000e-02        1.00000000000000000e-01
    1.000000e+00        1.00000000000000000e+00
    1.000000e+01        1.00000000000000000e+01
    1.000000e+02        1.00000000000000000e+02
    1.000000e+03        1.00000000000000000e+03
    1.000000e+04        1.00000000000000000e+04
    1.000000e+05        1.00000000000000000e+05
    1.000000e+06        1.00000000000000000e+06
    1.000000e+07        1.00000000000000000e+07
    1.000000e+08        1.00000000000000000e+08
    1.000000e+09        1.00000000000000000e+09
    1.000000e+10        1.00000000000000000e+10
    1.000000e+11        1.00000000000000000e+11
   10.000000e+11        1.00000000000000000e+12
   10.000000e+12        1.00000000000000000e+13
   10.000000e+13        1.00000000000000000e+14
   10.000000e+14        1.00000000000000000e+15
   10.000000e+15        1.00000000000000000e+16
   10.000000e+16        1.00000000000000000e+17
   10.000000e+17        1.00000000000000000e+18
   10.000000e+18        1.00000000000000000e+19
   10.000000e+19        1.00000000000000000e+20
   10.000000e+20        1.00000000000000000e+21
   10.000000e+21        1.00000000000000000e+22
   10.000000e+22        1.00000000000000000e+23
   10.000000e+23        1.00000000000000000e+24
   10.000000e+24        1.00000000000000000e+25
   10.000000e+25        1.00000000000000000e+26
   10.000000e+26        1.00000000000000000e+27
   10.000000e+27        1.00000000000000000e+28
   10.000000e+28        1.00000000000000000e+29
   10.000000e+29        1.00000000000000000e+30
   10.000000e+30        1.00000000000000000e+31
   10.000000e+31        1.00000000000000000e+32
   10.000000e+32        1.00000000000000000e+33
   10.000000e+33        1.00000000000000000e+34
   10.000000e+34        1.00000000000000000e+35
   10.000000e+35        1.00000000000000000e+36
   10.000000e+36        1.00000000000000000e+37
   10.000000e+37        1.00000000000000000e+38
@del t.rel,t.exe
 T.REL.5 [OK]
 T.EXE.5 [OK]

Now let's try PCC-20; it has some terrible faults (see the
9.000... entries); note that float == double = 36-bits for
PCC-20.

@cc t.c
[PCC: t.c]
MACRO:	t.c
LINK:	Loading
@t.exe
    1.000000e-37        1.00000000000000000e-37
    1.000000e-36        1.00000000000000000e-36
    1.000000e-35        1.00000000000000000e-35
    1.000000e-34        1.00000000000000000e-34
    1.000000e-33        1.00000000000000000e-33
    9.000000e-33        9.00000024923411926e-33
    9.000000e-32        9.00000024923411926e-32
    1.000000e-30        1.00000000000000000e-30
    1.000000e-29        1.00000000000000000e-29
    1.000000e-28        1.00000001490116112e-28
    1.000000e-27        1.00000000000000000e-27
    1.000000e-26        1.00000000000000000e-26
    1.000000e-25        1.00000000000000000e-25
    9.000000e-25        9.00000024923411926e-25
    1.000000e-23        1.00000000000000000e-23
    1.000000e-22        1.00000000000000000e-22
    1.000000e-21        1.00000000000000000e-21
    1.000000e-20        1.00000000000000000e-20
    1.000000e-19        1.00000000000000000e-19
    9.000000e-19        9.00000024923411926e-19
    1.000000e-17        1.00000000000000000e-17
    1.000000e-16        1.00000000000000000e-16
    1.000000e-15        1.00000000000000000e-15
    1.000000e-14        1.00000000000000000e-14
    1.000000e-13        1.00000000000000000e-13
    9.000000e-13        9.00000024923411926e-13
    9.000000e-12        9.00000024923411926e-12
    1.000000e-10        1.00000000000000000e-10
    1.000000e-09        1.00000000000000000e-09
    1.000000e-08        1.00000000000000000e-08
    1.000000e-07        1.00000000000000000e-07
    1.000000e-06        1.00000000000000000e-06
    1.000000e-05        1.00000000000000000e-05
    1.000000e-04        1.00000000000000000e-04
    1.000000e-03        1.00000000000000000e-03
    1.000000e-02        1.00000000000000000e-02
    1.000000e-01        1.00000000000000000e-01
    1.000000e+00        1.00000000000000000e+00
    1.000000e+01        1.00000000000000000e+01
    1.000000e+02        1.00000000000000000e+02
    1.000000e+03        1.00000000000000000e+03
    1.000000e+04        1.00000000000000000e+04
    1.000000e+05        1.00000000000000000e+05
    1.000000e+06        1.00000000000000000e+06
    1.000000e+07        1.00000000000000000e+07
    1.000000e+08        1.00000000000000000e+08
    1.000000e+09        1.00000000000000000e+09
    1.000000e+10        1.00000001490116112e+10
    1.000000e+11        1.00000001490116112e+11
    1.000000e+12        1.00000001490116112e+12
    1.000000e+13        1.00000000000000000e+13
    1.000000e+14        1.00000001490116112e+14
    1.000000e+15        1.00000001490116112e+15
    1.000000e+16        1.00000000000000000e+16
    1.000000e+17        1.00000000000000000e+17
    1.000000e+18        1.00000000000000000e+18
    1.000000e+19        1.00000000000000000e+19
    1.000000e+20        1.00000000000000000e+20
    1.000000e+21        1.00000000000000000e+21
    1.000000e+22        1.00000001490116112e+22
    1.000000e+23        1.00000000000000000e+23
    1.000000e+24        1.00000000000000000e+24
    1.000000e+25        1.00000000000000000e+25
    1.000000e+26        1.00000001490116112e+26
    1.000000e+27        1.00000001490116112e+27
    1.000000e+28        1.00000001490116112e+28
    1.000000e+29        1.00000001490116112e+29
    1.000000e+30        1.00000000000000000e+30
    1.000000e+31        1.00000001490116112e+31
    9.000000e+33        9.00000024923411926e+33
    1.000000e+33        1.00000000000000000e+33
    1.000000e+34        1.00000000000000000e+34
    1.000000e+35        1.00000000000000000e+35
    1.000000e+36        1.00000000000000000e+36
    1.000000e+37        1.00000000000000000e+37
    1.000000e+38        1.00000000000000000e+38
@
@; For comparison, here are the results on Sun OS 4.0 cc.
@; They appear to be correct.  The 9.99999 stuff is perhaps to be 
@; expected since the double column field width is a bit too wide for
@; 64-bit data.
@
@type b:t.lst
-----------------
PS:<BEEBE>T.LST.1
-----------------

    1.000000e-37        1.00000000000000007e-37
    1.000000e-36        9.99999999999999941e-37
    1.000000e-35        1.00000000000000001e-35
    1.000000e-34        9.99999999999999928e-35
    1.000000e-33        1.00000000000000006e-33
    1.000000e-32        1.00000000000000006e-32
    1.000000e-31        1.00000000000000008e-31
    1.000000e-30        1.00000000000000008e-30
    1.000000e-29        9.99999999999999943e-30
    1.000000e-28        9.99999999999999971e-29
    1.000000e-27        1.00000000000000004e-27
    1.000000e-26        1.00000000000000004e-26
    1.000000e-25        1.00000000000000004e-25
    1.000000e-24        9.99999999999999924e-25
    1.000000e-23        9.99999999999999960e-24
    1.000000e-22        1.00000000000000005e-22
    1.000000e-21        9.99999999999999908e-22
    1.000000e-20        9.99999999999999945e-21
    1.000000e-19        9.99999999999999975e-20
    1.000000e-18        1.00000000000000007e-18
    1.000000e-17        1.00000000000000007e-17
    1.000000e-16        9.99999999999999979e-17
    1.000000e-15        1.00000000000000008e-15
    1.000000e-14        9.99999999999999999e-15
    1.000000e-13        1.00000000000000003e-13
    1.000000e-12        9.99999999999999980e-13
    1.000000e-11        9.99999999999999939e-12
    1.000000e-10        1.00000000000000004e-10
    1.000000e-09        1.00000000000000006e-09
    1.000000e-08        1.00000000000000002e-08
    1.000000e-07        9.99999999999999955e-08
    1.000000e-06        9.99999999999999955e-07
    1.000000e-05        1.00000000000000008e-05
    1.000000e-04        1.00000000000000005e-04
    1.000000e-03        1.00000000000000002e-03
    1.000000e-02        1.00000000000000002e-02
    1.000000e-01        1.00000000000000006e-01
    1.000000e+00        1.00000000000000000e+00
    1.000000e+01        1.00000000000000000e+01
    1.000000e+02        1.00000000000000000e+02
    1.000000e+03        1.00000000000000000e+03
    1.000000e+04        1.00000000000000000e+04
    1.000000e+05        1.00000000000000000e+05
    1.000000e+06        1.00000000000000000e+06
    1.000000e+07        1.00000000000000000e+07
    1.000000e+08        1.00000000000000000e+08
    1.000000e+09        1.00000000000000000e+09
    1.000000e+10        1.00000000000000000e+10
    1.000000e+11        1.00000000000000000e+11
    1.000000e+12        1.00000000000000000e+12
    1.000000e+13        1.00000000000000000e+13
    1.000000e+14        1.00000000000000000e+14
    1.000000e+15        1.00000000000000000e+15
    1.000000e+16        1.00000000000000000e+16
    1.000000e+17        1.00000000000000000e+17
    1.000000e+18        1.00000000000000000e+18
    1.000000e+19        1.00000000000000000e+19
    1.000000e+20        1.00000000000000000e+20
    1.000000e+21        1.00000000000000000e+21
    1.000000e+22        1.00000000000000000e+22
    1.000000e+23        9.99999999999999916e+22
    1.000000e+24        9.99999999999999983e+23
    1.000000e+25        1.00000000000000009e+25
    1.000000e+26        1.00000000000000005e+26
    1.000000e+27        1.00000000000000001e+27
    9.999999e+27        9.99999999999999958e+27
    1.000000e+29        9.99999999999999914e+28
    1.000000e+30        1.00000000000000002e+30
    1.000000e+31        9.99999999999999964e+30
    1.000000e+32        1.00000000000000005e+32
    1.000000e+33        9.99999999999999946e+32
    1.000000e+34        9.99999999999999946e+33
    1.000000e+35        9.99999999999999969e+34
    1.000000e+36        1.00000000000000004e+36
    1.000000e+37        9.99999999999999954e+36
    1.000000e+38        9.99999999999999977e+37
@pop

[PHOTO:  Recording terminated  Fri 7-Oct-88 5:21PM]
-------
14-Oct-88 23:58:20-PDT,1947;000000000000
Received: from SIMTEL20.ARMY.MIL by SRI-NIC.ARPA with TCP; Fri, 14 Oct 88 23:56:00 PDT
Date: Sat, 15 Oct 1988  00:55 MDT
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: free() bug (CC 608, LIBC 235)

The attached program produces the following errors when compiled and
run with the -DDEBUG option:

[PHOTO:  Recording initiated  Sat 15-Oct-88 12:50AM]

$cc -DDEBUG tstchk
KCC:	tstchk
MACRO:	tstchk

EXIT
LINK:	Loading
$tstchk sri-nic.arpa
Host number for sri-nic.arpa: 26.0.0.73
Host number for : 26.0.0.73
free(): tried to free invalid block (0,,432006)
?Illegal instruction 0 at ABORT
?Undefined operation code
$cc tstchk
KCC:	tstchk
MACRO:	tstchk

EXIT
LINK:	Loading
$tstchk sri-nic.arpa
Host number for SRI-NIC.ARPA: 26.0.0.73
$pop

[PHOTO:  Recording terminated Sat 15-Oct-88 12:51AM]

TSTCHK.C:

#include <stdio.h>
#include <jsys.h>

#define	TRUE	1
#define	FALSE	0

char hname[100];

main(num, arg)
int	num;
char	*arg[];
{
    int ablock[5];
    int n[5];
    int	i, hnum;

    ablock[1] = _GTHSN;
    ablock[2] = (int) (arg[1] - 1);
    if (!jsys(GTHST, ablock)) {
	fprintf(stderr, "Host %s is not known.\n", arg[1]);
	exit(1);
    }
    hnum = ablock[3];
    for(i = 4; --i >= 0; hnum >>= 8) {
	n[i] = hnum&0xFF;
    }
#ifdef DEBUG
    printf("Host number for %s: %d.%d.%d.%d\n",
	    arg[1], n[0], n[1], n[2], n[3]);
#endif
    ablock[1] = _GTHNS;			/* want official name now */
    ablock[2] = (int) (hname - 1);	/* where to put it */
    if (!jsys(GTHST, ablock))	{	/* if can't get the official */
	fprintf(stderr, "Host %s is not known.\n", arg[1]);
	exit(1);
    }
    for(i = 4; --i >= 0; ablock[3] >>= 8) {
	n[i] = ablock[3]&0xFF;
    }
    printf("Host number for %s: %d.%d.%d.%d\n",
	    hname, n[0], n[1], n[2], n[3]);
}
16-Dec-88 20:04:05-PST,2211;000000000000
Received: from WSMR-SIMTEL20.ARMY.MIL by SRI-NIC.ARPA with TCP; Fri, 16 Dec 88 20:02:56 PST
Date: Fri, 16 Dec 1988  21:03 MST
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
Subject: [WANCHO: free() bug (CC 608, LIBC 235)]

Somehow I missed even an acknowledgement that this report was
received...

--Frank
--------------------

Date: Saturday, 15 October 1988  00:55-MDT
From: Frank J. Wancho <WANCHO>
To:   BUG-KCC at SRI-NIC.ARPA
cc:   WANCHO
Re:   free() bug (CC 608, LIBC 235)

The attached program produces the following errors when compiled and
run with the -DDEBUG option:

[PHOTO:  Recording initiated  Sat 15-Oct-88 12:50AM]

$cc -DDEBUG tstchk
KCC:	tstchk
MACRO:	tstchk

EXIT
LINK:	Loading
$tstchk sri-nic.arpa
Host number for sri-nic.arpa: 26.0.0.73
Host number for : 26.0.0.73
free(): tried to free invalid block (0,,432006)
?Illegal instruction 0 at ABORT
?Undefined operation code
$cc tstchk
KCC:	tstchk
MACRO:	tstchk

EXIT
LINK:	Loading
$tstchk sri-nic.arpa
Host number for SRI-NIC.ARPA: 26.0.0.73
$pop

[PHOTO:  Recording terminated Sat 15-Oct-88 12:51AM]

TSTCHK.C:

#include <stdio.h>
#include <jsys.h>

#define	TRUE	1
#define	FALSE	0

char hname[100];

main(num, arg)
int	num;
char	*arg[];
{
    int ablock[5];
    int n[5];
    int	i, hnum;

    ablock[1] = _GTHSN;
    ablock[2] = (int) (arg[1] - 1);
    if (!jsys(GTHST, ablock)) {
	fprintf(stderr, "Host %s is not known.\n", arg[1]);
	exit(1);
    }
    hnum = ablock[3];
    for(i = 4; --i >= 0; hnum >>= 8) {
	n[i] = hnum&0xFF;
    }
#ifdef DEBUG
    printf("Host number for %s: %d.%d.%d.%d\n",
	    arg[1], n[0], n[1], n[2], n[3]);
#endif
    ablock[1] = _GTHNS;			/* want official name now */
    ablock[2] = (int) (hname - 1);	/* where to put it */
    if (!jsys(GTHST, ablock))	{	/* if can't get the official */
	fprintf(stderr, "Host %s is not known.\n", arg[1]);
	exit(1);
    }
    for(i = 4; --i >= 0; ablock[3] >>= 8) {
	n[i] = ablock[3]&0xFF;
    }
    printf("Host number for %s: %d.%d.%d.%d\n",
	    hname, n[0], n[1], n[2], n[3]);
}
15-Jan-89 21:02:28-PST,608;000000000000
Mail-From: MIMI created at 15-Jan-89 20:58:59
Date: Sun, 15 Jan 89 20:58:57 PST
From: Mimi Recker <[email protected]>
Subject: strCMP() bug???
To: [email protected]
Message-ID: <[email protected]>

seems to apply to other case insentive str ops too...

[PHOTO:  Recording initiated  Sun 15-Jan-89 8:56pm]

@ty test.c
main()
{
   (strcmp("aaa", "aaa")==0) ? puts("cmp same") : puts("cmp not same");
   (strCMP("aaa", "AAA")==0) ? puts("CMP same") : puts("CMP not same");
}
@test
cmp same
CMP not same
@pop

[PHOTO:  Recording terminated Sun 15-Jan-89 8:56pm]
-------
16-Jan-89 10:10:02-PST,255;000000000000
Mail-From: MIMI created at 16-Jan-89 09:56:11
Date: Mon, 16 Jan 89 09:56:08 PST
From: Mimi Recker <[email protected]>
Subject: re: bug in strCMP
To: [email protected]
Message-ID: <[email protected]>

Ooops...never mind.
-------
16-Jan-89 10:25:41-PST,378;000000000000
Mail-From: KLH created at 16-Jan-89 10:25:05
Date: Mon, 16 Jan 89 10:24:46 PST
From: Ken Harrenstien <[email protected]>
Subject: re: bug in strCMP
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

I bet you forgot to #include <nic/strung.h>, right?
-------
18-Jan-89 12:52:01-PST,1057;000000000000
Received: from VERA.NADA.KTH.SE ([130.237.222.17]) by SRI-NIC.ARPA with TCP; Wed, 18 Jan 89 12:50:22 PST
Date: Wed 18 Jan 89 21:49:44
From: Jan Michael Rynning <[email protected]>
Subject: <C.KCC.CC>*.* - Not found.
To: [email protected]
Organization: Royal Institute of Technology, Stockholm, Sweden.
Address: NADA, KTH, S-100 44 Stockholm, Sweden.
Telephone: +46-8-7906288
Message-ID: <[email protected]>

I am trying to update my KCC compiler sources, but when I ask for a
directory listing of <C.KCC.CC>*.* yor FTP server says "Not found".
Did I look in the wrong place, did you move the compiler sources to
another directory, or is <C.KCC.CC> protected so I can't read it?

Jan Michael Rynning,			[email protected]
Department of Numerical Analysis	If you can't fully handle domains:
  and Computing Science,		ARPA: jmr%[email protected]
Royal Institute of Technology,		UUCP: {uunet,mcvax,...}!nada.kth.se!jmr
S-100 44 Stockholm,			BITNET: jmr@sekth
Sweden.					Phone: +46-8-7906288
-------
 1-Feb-89 12:59:04-PST,930;000000000000
Mail-From: TODD created at  1-Feb-89 12:56:14
Date: Wed, 1 Feb 89 12:56:08 PST
From: Todd Koumrian <[email protected]>
Subject: out of mem
To: [email protected]
Location: SRI-International  Room EJ274, Phone: (415)859-5905
Message-ID: <[email protected]>

[copy of message sent to sys-staff]

Our system software hasn't been treating me very nicely today.
My emacs died this morning with an "Internal Error at XXXXXX", where
XXXXXX was an address which I lost (great help, huh), and then KCC
says:

!cc pdcchk.c
KCC:    pdcchk
"pdcchk.c", line 255: Fatal error - Out of memory
       (p.1 l.255): NG", "SD",     "BJ", "BL", "SH", "DS", "BI", "" };  struct 

Granted that my program is large, but not that large.  Note that I am
not implying that the two problems were necessarily related, since although
they both occurred today from the same job, they were hours appart.

Todd
-------
 1-Feb-89 14:51:10-PST,532;000000000000
Mail-From: KLH created at  1-Feb-89 13:55:40
Date: Wed, 1 Feb 89 13:55:33 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: out of mem
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Use CCX (multi-section version of KCC) to compile your program.  For whatever
reason, your code is causing KCC to dynamically allocate more internal
objects/space than will fit in its single-section version.
-------
30-Jan-89 14:40:04-PST,2719;000000000015
Return-Path: <[email protected]>
Received: from SCIENCE.UTAH.EDU by SRI-NIC.ARPA with TCP; Mon, 30 Jan 89 14:39:51 PST
Date: Mon 30 Jan 89 15:36:58-MST
From: "Nelson H.F. Beebe" <[email protected]>
Subject: Bug in KCC 608 [31-Aug-88 18:51:10]
To: [email protected]
cc: [email protected], [email protected]
X-US-Mail: "Center for Scientific Computing, South Physics, University of Utah, Salt Lake City, UT 84112"
X-Telephone: (801) 581-5254
Message-ID: <[email protected]>

A user reported a KCC bug (and isolated it from a much larger
program) which I've further determined is due to a missing ADJSP
17,-3 after a PUSHJ 17,CHOP.  If the code at the end of this
report is compiled as

kcc bug1

and run, it produces many error messages.  If compiled as

kcc -DTWOSTEP bug1

it runs without errors.

The only difference is the breaking up of a long expression into
two parts.  Compilation with -S revealed the missing ADJSP 17,-3
at line 76 in the .fai file.

We are running KCC 608 [31-Aug-88 18:51:10].

Here is the test program:

#include <stdio.h>
#define T 20
#define C 11
#define M  3

int a[M] = {1, 1, 1};
int y[M] = {0, 3, 5};
float b[M] = {0.0, 0.004, 0.02};
float l[M] = {0.0, 0.4, 0.6};

main()
{
  int t,x;  
  int patch, best_patch;  
  float f0[C], f1[C];
  float prob, best_prob;

  f1[0] = 0;
  for(x=1; x<C; x++)
    f1[x] = 1.0;

  for(t=T; t>=0; t--)
  {
    printf("\n\nt=%4d: %8s %8s %8s", t, "energy", "prob", "patch");
    for(x=0; x<C; x++)
    {
      best_prob = -1.0;
      best_patch = -1;
      for(patch=0; patch<M; patch++)
      {
#ifdef TWOSTEP
	prob =  l[patch]  * f1[chop(x-a[patch]+y[patch],0,C-1)];
        prob += (1.0-l[patch]) * f1[chop(x-a[patch],0,C-1)];
#else
	prob =  (l[patch]  * f1[chop(x-a[patch]+y[patch],0,C-1)])
               + ((1.0-l[patch]) * f1[chop(x-a[patch],0,C-1)]);
#endif
	if(prob>1.0 || prob<0.0)
	    fprintf(stderr,"\nError: prob1=%f", prob);
	prob *= 1.0-b[patch];
	if(prob>1.0 || prob<0.0)
	    fprintf(stderr,"\nError: prob2=%f", prob);
	if(prob>best_prob)
	{
	  best_prob = prob;
	  best_patch = patch;
	}
      }
      f0[x] = best_prob;
      printf("\n%8s%8d %8.5f %8d", "", x, best_prob, best_patch);
    }
    for(x=0; x<C; x++)  /* update array f1 */
      f1[x] = f0[x];
  }
  putchar('\n');  /*Put a linefeed at the end of the output*/
}
/* Define "chop(a,b,c)", a function that returns b if a<b, c if a>c, */
/* or a if b<a<c */
int chop(a,b,c) 
int a,b,c;
{
  if(a<b) 
    a = b;
  if(a>c)
    a = c;
  if(a<0 || a>=C)
  {
    printf("\nError: chop = %d", a);exit(1);
  }
  return(a);
}
-------
 3-Feb-89 17:50:29-PST,590;000000000001
Mail-From: KLH created at  3-Feb-89 17:50:24
Date: Fri, 3 Feb 89 17:50:24 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Bug in KCC 608 [31-Aug-88 18:51:10]
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

OK, I've fixed this bug as of KCC 609 (available as SYS:CC.EXE on SRI-NIC
(ditto CCX)).  As usual, optimization oversight (it would have worked if
you had compiled with optimization disabled, you didn't mention trying that.)
-------
 7-Feb-89 21:39:42-PST,445;000000000000
Received: from WSMR-SIMTEL20.ARMY.MIL by SRI-NIC.ARPA with TCP; Tue, 7 Feb 89 21:33:41 PST
Date: Tue, 7 Feb 1989  22:32 MST
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: New versions?

I see that LIBC.REL was updated last November and CC.EXE updated last
week.  What's new/fixed?

--Frank
 8-Feb-89 14:40:51-PST,534;000000000000
Mail-From: KLH created at  8-Feb-89 12:46:56
Date: Wed, 8 Feb 89 12:37:07 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: New versions?
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

LIBC.REL has a new SIGVEC which fixes a signal handling bug (some kinds of
multiple interrupts got lost).  CC.EXE fixes Yet Another Obscure Optimization
Bug.  Nothing new, really.
-------
 4-Mar-89 15:00:06-PST,1502;000000000000
Mail-From: TODD created at  4-Mar-89 14:55:13
Date: Sat, 4 Mar 89 14:55:12 PST
From: Todd Koumrian <[email protected]>
Subject: piping w/TOPS-20 extended addressing
To: [email protected]
cc: [email protected]
Location: SRI-International  Room EJ274, Phone: (415)859-5905
Message-ID: <[email protected]>

I've noticed this problem before, but I didn't comment on it at that time.
The problem has to do when piping the output of one KCC program through
another KCC program (or the same one), when the program has been linked
with the extended-section addressing module, C:LIBCKX.

The programs produce the correct results, but fail to terminate (never do),
and I must control-C out.  The un-extended-section versions of the same
programs WILL execute and terminate properly.

Here's an INFO FORK after I ^C'ed out of a 2-stage pipline that never
terminated:
 => GROK (1): ^C from SLEEP at 1,,427507, 0:01:57.2
       Fork 2: HALT at 1,,403044, 0:00:05.0

Grok is a string-search program of mine, and I was piping the output of
one search through another search.  The version executed was linked with
the extended-section addressing module.  Grok always explicitly terminates
by calling exit(), with either 0, 1, or 2.

This same program linked without the extended-section addressing module
executes the same sequence correctly and terminates.  I haven't been able
to duplicate the non-termination problem with non-extended addressing
programs.
-------
 5-Mar-89 09:38:43-PST,1046;000000000000
Received: from SCIENCE.UTAH.EDU by SRI-NIC.ARPA with TCP; Sun, 5 Mar 89 09:37:27 PST
Date: Sun 5 Mar 89 10:39:04-MST
From: "Nelson H.F. Beebe" <[email protected]>
Subject: Preprocessor pre-ANSI behavior
To: [email protected]
cc: [email protected]
X-US-Mail: "Center for Scientific Computing, South Physics, University of Utah, Salt Lake City, UT 84112"
X-Telephone: (801) 581-5254
Message-ID: <[email protected]>

The KCC C preprocessor still works like old PCC (and like
UNIX cc) in substituting n in \n, but unlike the latter,
raises an error when it finds \k from the substitution.  GNU
gcc does not substitute n in \n, which I believe is the ANSI
intent:

[PHOTO:  Recording initiated  Sun 5-Mar-89 10:32AM]

 TOPS-20 Command processor 5(712)

@type bug.c
#define M(n) "hello\n"
char* X = M(k);

@kcc -E bug.c
char* X = "hello\k";

! PCC-20 does this too:
@pcc:cpp bug.c 
# 1 "bug.c"

char* X =  "hello\k";
@pop

[PHOTO:  Recording terminated  Sun 5-Mar-89 10:33AM]
-------
 7-Mar-89 16:47:17-PST,1942;000000000000
Received: from SCIENCE.UTAH.EDU by SRI-NIC.ARPA with TCP; Tue, 7 Mar 89 16:42:28 PST
Date: Tue 7 Mar 89 17:43:51-MST
From: "Nelson H.F. Beebe" <[email protected]>
Subject: Another KCC preprocessor bug
To: [email protected]
cc: [email protected]
X-US-Mail: "Center for Scientific Computing, South Physics, University of Utah, Salt Lake City, UT 84112"
X-Telephone: (801) 581-5254
Message-ID: <[email protected]>

Last night, I was reading Peter Plauger's column in the C
Language Journal, and came across a remark about ANSI C requiring
preprocessor statements to occur on a single line, BUT that
because comments are white space, a multi-line comment can be
used to code a preprocessor statement in multiple lines.  I have
need of this in code which has long statements like

#if    (ANADEX | APPLEIMAGEWRITER | DECLA75 | DECLN03PLUS | EPSON)
...
#endif

and

#if    (EPSONLQ | FUJITSUDL2400 | GP300 | HPDESKJET | IBM4202 | TOSHIBAP1351)
...
#endif

Currently, these are split into 2 groups containing identical
statements, in order to keep to an 80-char limit needed for
portability.   I there tried the following test programs on
several compilers:

foo.c:
#define ONE 1
#define TWO 2

#if (ONE | \
	TWO)
char* s = "both";
#else
char* s = "neither";
#endif

foo2.c:
#define ONE 1
#define TWO 2

#if (ONE | /* more...
	... */ TWO)
char* s = "both";
#else
char* s = "neither";
#endif

I have tried:

PC DOS:	 Microsoft C 5.0 and Turbo C 2.0
Silicon Graphics (AT&T Sys V): cc
GNU: gcc
SunOS: cc
HPUX: cc
TOPS-20: pcc-20 and kcc-20

All but kcc-20 gave the expected result:

char* s = "both";

KCC-20 gave that for foo.c, but for foo2.c, GAVE NO OUTPUT.  That
seems to me to be a bug.  (I used "kcc -E foo2.c").  Even if it
got the wrong answer for the test, it should have given me the
other branch with char* s = "neither";.


-------
 7-Mar-89 17:55:33-PST,571;000000000000
Mail-From: KLH created at  7-Mar-89 17:17:33
Date: Tue, 7 Mar 89 17:17:25 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Another KCC preprocessor bug
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Well, I haven't had much time for KCC lately, but this was an easy one
and has been fixed.  Not installed yet, though (waiting for time to get
around to the other bug reports).  If you really need it I could set it up.
-------
 8-Mar-89 02:29:57-PST,1500;000000000000
Received: from ifi.uio.no by SRI-NIC.ARPA with TCP; Wed, 8 Mar 89 02:27:33 PST
Received: from skade.uio.no by ifi.uio.no (5.59++/1.15) with SMTP 
	id AA22084; Wed, 8 Mar 89 11:26:55 +0100
Received: from TONE by skade.uio.no; Wed, 8 Mar 89 11:28:29 +0100
Date: Wed 8 Mar 89 11:22:03
From: Rein Tollevik <REIN%[email protected]>
Subject: Bug in KCC v607
To: [email protected]
Message-Id: <12476332632.16.REIN@TONE>

KCC don't like the ^= assignment in the following peace of code.  It
works OK with an ordinary assignment.

							Rein

#define KSIZE 9
makekey(a, b)
char *a, *b;
{
	register int i;
	long t;
	char temp[KSIZE + 1];

	for(i = 0; i < KSIZE; i++)
		temp[i] = *a++;
	time(&t);
	t += getpid();
	for(i = 0; i < 4; i++)
		temp[i] ^= (t>>(8*i))&0377;
	crinit(temp, b);
}


[PHOTO:  Recording initiated  Wed 8-Mar-89 11:15AM]

TONE@kcc edbug
KCC:    edbug
"edbug.c", line 17: Internal error - unknown assignment lvalue op (node 68: 34 N
_CAST)
       (makekey+15, p.1 l.16): emp[i] ^= (t>>(8*i))&0377;  crinit(temp, b); } 

"edbug.c", line 17: Internal error - gaddress of unknown op (node 68: 34 N_CAST)
       (makekey+15, p.1 l.16): emp[i] ^= (t>>(8*i))&0377;  crinit(temp, b); } 

"edbug.c", line 17: Internal error - gaddress of unknown op (node 68: 34 N_CAST)
       (makekey+15, p.1 l.16): emp[i] ^= (t>>(8*i))&0377;  crinit(temp, b); } 

?KCC - 3 error(s) detected
TONE@po

[PHOTO:  Recording terminated Wed 8-Mar-89 11:15AM]
-------
 9-Mar-89 17:16:21-PST,1665;000000000000
Received: from SCIENCE.UTAH.EDU by SRI-NIC.ARPA with TCP; Thu, 9 Mar 89 17:15:20 PST
Date: Thu 9 Mar 89 18:14:39-MST
From: Pieter <[email protected]>
Subject: FORKEX.C bug and correction
To: [email protected]
cc: [email protected]
Snail: Center for Scientific Computing
Snail: 224 Physics South
Snail: Department of Mathematics
Snail: University of Utah
Snail: Salt Lake City, UT 84112, USA, Terra
Telephone: 1-801-581-6286
Message-ID: <[email protected]>

    I've been trying to port some code from Unix which uses the
execlp function.  Today I finally tracked down the problem.
It occurs in the FORKEX module in function revstack.  Here is
the fix.  The two lines marked with '|' are the ones.

Pieter
[email protected]


/* REVSTACK - auxiliary for execl*() routines.
**	Reverses an array of pointers on the stack.
** On the PDP-10 an arg list like arg1, arg2, ... 0 is stored on
** the stack such that 0 is at the lowest address, arg1 at highest.
** We need to reverse this ordering so we can treat it like a normal
** argv array (with a null pointer as the last element).
*/
static char **
revstack(av)
char **av;
{
    register char **t, **b, *tmp;	/* Top and bottom pointers */
    register int i;

    for (t = b = av; *t; --t);	/* Back up to top of array (a null ptr) */
    av = t;			/* Remember where top is */
    i = (1 + b - t) / 2;	/* Find # of elements to swap in array */
    for (; i > 0; --i) {
	tmp = *t;		/* Swap elements, and bump ptrs closer. */
|	*t++ = *b;
|	*b-- = tmp;
    }
    return av;			/* Return ptr to top of reversed array */
}
-------
 9-Mar-89 17:26:07-PST,473;000000000000
Mail-From: KLH created at  9-Mar-89 17:24:16
Date: Thu, 9 Mar 89 17:24:07 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: FORKEX.C bug and correction
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Thanks for tracking down that bug and fixing it.  Gack... the top/bottom
higher#/lower# confusion strikes once again!
-------
10-Mar-89 04:51:20-PST,604;000000000000
Mail-From: KLH created at 10-Mar-89 04:46:17
Date: Fri, 10 Mar 89 04:46:13 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Bug in KCC v607
To: REIN%[email protected], [email protected]
cc: [email protected]
In-Reply-To: <12476332632.16.REIN@TONE>
Message-ID: <[email protected]>

Sorry, but I cannot reproduce this problem.  I tried compiling that code
with version 607 and had no problems.  You might wish to FTP a more recent
version (SYS:CC.EXE is now version 609), just in case your copy got
clobbered somehow.  Let me know if you find any more details.
-------
10-Mar-89 06:21:45-PST,1614;000000000000
Mail-From: KLH created at 10-Mar-89 06:14:20
Date: Fri, 10 Mar 89 06:14:16 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: piping w/TOPS-20 extended addressing
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

OK, I found a bug in the way wait() was coded which caused it to not work
in extended addressing, and fixed it (not yet installed, too tired).
Piping was involved only to the extent that it invoked an inferior fork
and waited for it to stop.

Unfortunately, I found a more serious bug which is much harder to fix.
There is no way I know of on TOPS-20 to suspend the current process
until any one of its inferiors terminates.  WFORK% lets you either
wait for a SPECIFIC inferior, or wait for ALL inferiors to terminate,
but you can't wait for ANY inferior.  Really amazing brain damage
here.

The only way out of this I can think of is to loop forever doing a GFRKS%
to examine the fork structure by hand, with a sleep period somewhere in the
loop to avoid burning too much CPU time.  This not only eats more cycles,
it imposes a certain delay in recognizing that a fork has died.  It would
be possible to use .ICIFT (Inferior Fork Termination PSI) but this is even
more complicated and would require (1) the overhead of PSI activation for
every C program, plus (2) special code to avoid interfering with users who
want to handle SIGCHLD signals (currently implemented, by the way).

If anyone has comments on this I'd appreciate them.

--Ken
-------
12-Mar-89 16:10:37-PST,1143;000000000000
Received: from ifi.uio.no by SRI-NIC.ARPA with TCP; Sun, 12 Mar 89 16:04:33 PST
Received: from skade.uio.no by ifi.uio.no (5.59++/1.15) with SMTP 
	id AA15597; Mon, 13 Mar 89 01:05:13 +0100
Received: from SIRI by skade.uio.no; Mon, 13 Mar 89 01:06:42 +0100
Date: Mon 13 Mar 89 00:43:01
From: Rein Tollevik <REIN%[email protected]>
Subject: Re: Bug in KCC v607
To: KLH%SRI-NIC.ARPA%[email protected]
Cc: REIN%tone%ifi.uio.no%[email protected],
        bug-kcc%SRI-NIC.ARPA%[email protected]
In-Reply-To: <[email protected]>
Message-Id: <12477527020.141.REIN@SIRI>

Yes, it seemed as our version of KCC was a little out of date.  I have
grabbed the source files with version numbers different from what we had
and recompiled KCC, and now the problem has gone.  Sorry for any
inconvenience I have brought to you.

Some of the version numbers was lower than ours, I think this was source
files I have earlier received patches for.  The patches didn't seem to
have been applied to those files, is that true or have I missed
something?  The files in question are ccjskp.c, ccopt.c and ccstmt.c

							Rein
-------
13-Mar-89 13:39:21-PST,1306;000000000000
Received: from ifi.uio.no by SRI-NIC.ARPA with TCP; Mon, 13 Mar 89 13:34:18 PST
Received: from skade.uio.no by ifi.uio.no (5.59++/1.15) with SMTP 
	id AA22746; Mon, 13 Mar 89 22:33:53 +0100
Received: from ifi.uio.no by skade.uio.no; Mon, 13 Mar 89 22:36:33 +0100
Received: from SRI-NIC.ARPA by ifi.uio.no (5.59++/1.15) with SMTP 
	id AA22742; Mon, 13 Mar 89 22:33:11 +0100
Date: Mon, 13 Mar 89 13:21:27 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Bug in KCC v607
To: REIN%[email protected], KLH%SRI-NIC.ARPA%[email protected]
Cc: REIN%tone%ifi.uio.no%[email protected],
        bug-kcc%SRI-NIC.ARPA%[email protected], [email protected]
In-Reply-To: <12477527020.141.REIN@SIRI>
Message-Id: <[email protected]>

Yes, the source files in the KCCDIST: distribution have not been updated
with the patches.  This is because typically there are other changes happening
which are unrelated to the bug fixes, and I am trying to keep the source
distribution consistent.  That is why I usually recommend just getting the
binary from SYS:CC.EXE (or CCX.EXE) if possible, since the source distribution
is out of date as soon as any change happens.  If there is a real need for
the latest source then I could probably arrange for an update, but it is
a lot of work.
-------
15-Mar-89 15:08:07-PST,1368;000000000000
Mail-From: KLH created at 15-Mar-89 15:06:29
Date: Wed, 15 Mar 89 15:06:26 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: piping w/TOPS-20 extended addressing
To: [email protected]
cc: [email protected], [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

    From the 6.1 JSYS manual entry for WFORK%:

    ACCEPTS IN AC1:	inferior process handle, or -4 in the right half to
		    wait for any one of the inferior processes to terminate

    Doesn't -4 do what you want?

			    Stu

Hmmm, this is weird.  My most recent (V6.0, 12/84) JSYS manual says
"... or -4 (.FHINF) in the right half to wait for all of the inferior
processes to terminate."  There are several change markings for the
description of WFORK%, all of which have to do with changing the
meaning of .FHINF from "any one" to "all".  My V5.1 (12/82) manual has
the old wording of "any one", and our online documentation (file
creation date 3/83) has the same wording.

To settle the issue I resorted to the source itself (how can anyone
LIVE without source?), and looked at WFORK in FORK.MAC.  Sure looks
like the "any one" interpretation is correct -- which is good news.
Thanks, Stu.  I can't help but wonder how some DEC bozo managed to
screw this one up.

--Ken
-------
 6-Apr-89 23:47:50-PDT,1000;000000000000
Received: from XX.LCS.MIT.EDU by SRI-NIC.ARPA with TCP; Thu, 6 Apr 89 23:45:39 PDT
Received: from KICKI.STACKEN.KTH.SE ([130.237.234.220]) by XX.LCS.MIT.EDU with TCP/SMTP; Fri 7 Apr 89 02:27:18-EDT
Return-Path: <@XERXES.STACKEN.KTH.SE:[email protected]>
Received: from XERXES.STACKEN.KTH.SE by KICKI.STACKEN.KTH.SE; Fri, 7 Apr 89  8:31:04 +0200
Received: from AIDA.CSD.UU.SE by XERXES with Cafard; Fri, 7 Apr 89 08:29:39 O
Date: Fri 7 Apr 89 08:00:11
From: Per-Erik Martin <[email protected]>
To: [email protected]
Subject: open() doesn't create O_RDONLY files
Message-ID: <[email protected]>


The unix-call open() creates a non-existing file when called with
O_WRONLY|O_CREAT or O_RDWR|O_CREAT, as it should, but not with
O_RDONLY|O_CREAT. The bug may be in _get_jfn() which, as far as I
can see, call GTJFN with GJ%OLD when O_RDONLY is set.
KCC-5, version 603, bye the way...

~pem

(Per-Erik Martin, ZYX Sweden AB, +46 18 696763, [email protected])
-------

12-May-89 21:04:34-PDT,1723;000000000000
Received: from WSMR-SIMTEL20.ARMY.MIL by SRI-NIC.ARPA with TCP; Fri, 12 May 89 20:59:17 PDT
Date: Fri, 12 May 1989  21:58 MDT
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: Suggestion for a generic callsub()

Some of the programs I write in C need to call routines in existing
REL files for which I do not have the sources.  So, rather than use
the #asm construct, I devised a little function, borrowed from code in
jsys.c and attached below, which I believe would be useful to include
in LIBC in some similar form.

--Frank
--------------------

int
callsub(routine, ablock)
int routine, *ablock;
{
#asm
	skipn	16,-2(17)	/* get address of ac block */
	 jrst cbad		/*  if null pointer, fail! */
	move 15,-1(17)		/* get the routine arg */
	dmove	1,1(16)		/* first two acs */
	dmove	3,3(16)		/* and next two */
	call	(15)
	 erjmpa call0
	jrst call1		/* won */
	jrst call2		/* for catching default cases */
	jrst call3		/* extra sure for default cases */

call0:	movem 1,0(16)		/* 0 Set ablock[0] to the system error code */
call0a:	tdza 5,5		/* 0 these are the returns.  +0 means lost. */
call1:	  movei 5,1		/* +1 means win with a +1 return. */
	jrst calle
call2:	skipa 5,[2]		/* +2 means won with +2, */
call3:	  movei 5,3		/* +3 won with +3. */
calle:	dmovem	1,1(16)		/* put return values back */
	dmovem	3,3(16)		/* other two acs */
	skipa 1,5		/* get return value */
cbad:	 setzb 1,(16)		/*  bad class or flags, return 0 with err# 0 */
				/*  (Note this is safe even if AC16 is 0!) */
	popj 17,		/* return to user */

#endasm
}
18-Jul-89 05:42:22-PDT,1566;000000000000
Received: from sunic.sunet.se by SRI-NIC.ARPA with TCP; Tue, 18 Jul 89 05:38:00 PDT
Received: by sunic.sunet.se (5.61+IDA/KTH/LTH/1.65)
	id AAsunic23078; Tue, 18 Jul 89 14:37:26 +0200
Received: by zyx.ZYX.SE (5.57++/smail2.2/02-27-88)
	id AA14097; Tue, 18 Jul 89 14:15:08 MET
Received: from lynx.ZYX.SE 
	by pepsi.zyx.SE (13.1/smail2.2/07-06-88)
	id AA11721; Tue, 18 Jul 89 14:14:08 met
Received: by lynx.ZYX.SE (13.1/smail2.2/07-06-88)
	id AA15200; Tue, 18 Jul 89 14:13:14 met
Date: Tue, 18 Jul 89 14:13:14 met
From: [email protected] (Per-Erik Martin)
Message-Id: <[email protected]>
To: [email protected]
Subject: v603


Hi!

When I compile this with -O it doesn't work. It behaves as if the pointer
increment has  disappeared;  the same first character is printed over and
over again. If I compile with -O=parse+gen it works fine.

					~pem

-------------------------------------------------------------------------------
- Per-Erik Martin, ZYX Sweden AB, Bangardsgatan 13, S-753 20  Uppsala, Sweden -
- Email: [email protected]                                                           -
-------------------------------------------------------------------------------

----8<------------------------------------------------------------------
void
pr(s)
     char *s;
{
  while (*s)
    {
      switch (*s) {
      case ' ': case '\t': case '\n': case '\r': case '\\':
	putchar('\\');
      }
      putchar(*s);
      s += 1;
    }
}
----8<------------------------------------------------------------------
18-Jul-89 05:52:03-PDT,681;000000000000
Mail-From: KLH created at 18-Jul-89 05:48:56
Date: Tue, 18 Jul 89 05:48:52 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: v603
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

Sigh.  Would you believe that bug was reported and fixed just a few
weeks ago?  It has to do with "cp += 1" where cp is a char pointer; it
can be gotten around by using "cp++" instead.  The current SRI-NIC
binary (v.610) includes the compiler fix; since I'm in the middle
of upgrading KCC to ANSI I'd rather not extract the source fix unless
you really want it.
-------
 9-Nov-89 16:18:46-PST,2036;000000000000
Received: from science.utah.edu by NIC.DDN.MIL with TCP; Thu, 9 Nov 89 16:14:19 PST
Date: Thu 9 Nov 89 16:48:32-MST
From: "Nelson H.F. Beebe" <[email protected]>
Subject: Infinite loop in KCC write() with interrupts off
To: [email protected]
cc: [email protected]
X-US-Mail: "Center for Scientific Computing, South Physics, University of Utah, Salt Lake City, UT 84112"
X-Telephone: (801) 581-5254
Message-ID: <[email protected]>

A colleague reported today an infinite loop in KCC write()
that I've just tracked down.  He has a small portable editor
that runs on several micros and minis, as well as the
DEC-20.  It disables interrupts to ensure that it has
control of the environment, particularly so students cannot
Ctl-C out of it, loosing their edits.

In the KCC implementation of write(), there is an infinite
loop (for (;;)) which continues looping retrying the I/O if
outsys() gets an interrupt return.  When interrupts are
disabled, it seems to loop forever.

To recreate the problem, run the following program in a
directory with working and permanent storage set to 10
pages; during the 7th call to outsys(), the loop will occur
if code is added to suppress interrupts (e.g. STIW% with ac1
= -5, ac2 = 0, ac3 = 0), and otherwise, the program will
terminate with the error

?File or swapping space exceeded at 411325

The immediate workaround we are applying is to replace his
single write() call with a jsys(SOUT,...); he already had
code to catch a failing write and do something intelligent
for the user (e.g. "Your disk quota has been used up.  Try
saving the file in the public scratch directory instead.").

#include <stdio.h>
main(){
char buf[4096];
int i,x;
FILE *fp;
        fp = fopen("FOO.","w");
     for(i=0;i<4096;++i) buf[i]= 'X';
     while(1){
      fprintf(stderr,"Write=");
      x=write(fileno(fp),buf,4096);
      fprintf(stderr,"%d\n",x);
      if(x == 0 || x == -1 || x < 4096) break;
    }
    fclose(fp);
}
-------
 9-Nov-89 17:04:37-PST,788;000000000001
Mail-From: KLH created at  9-Nov-89 17:01:22
Date: Thu, 9 Nov 89 17:01:15 PST
From: Ken Harrenstien <[email protected]>
Subject: Re: Infinite loop in KCC write() with interrupts off
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

In the WRITE.C module there is a line:
	/* SOUT% error to be turned into SIGXFSZ signal */

Put a "return 0;" statement just before that.

I originally thought that the T20 errors IOX11 and IOX34 (interrupts
.ICQTA, .ICMSE) should be turned into SIGXFSZ, but it turns out that SIGXFSZ
is only associated with setrlimit() and has nothing to do with the
EDQUOT or ENOSPC errors, so that code is bogus anyway.  Sigh.
-------
26-Feb-90 08:57:49-PST,1486;000000000011
Received: from WSMR-SIMTEL20.ARMY.MIL by NIC.DDN.MIL with TCP; Mon, 26 Feb 90 08:28:51 PST
Date: Mon, 26 Feb 1990  09:14 MST
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: memcpy bug?

With CC 610 and LIBC 239:

On occassion I port utility programs written for the Unix world to
this system.  I had no major problems with one program until a new
module was added about six months ago.  Even after applying all the
tricks, such as adding masking where appropriate and defining long
names to shorter ones, it still didn't work.  It indicated the test
file was faulty when it wasn't.  The Unix version did not have this
problem.

This past week I gave it another shot, sprinkling in printf statements
in the local and Unix versions to compare output.  I *finally* tracked
the problem down to an apparent failure in memcpy().  Fortunately, I
was able to comment out the use of memcpy() because the code already
had a byte-by-byte alternative.

I tried explicit casting of the memcpy args.  That made no difference.
Because the code is convoluted, there may be some dependencies that a
code extract demonstrating the problem may mask.  It may not be a
problem with memcpy at all.  So, if you wish, I can ftp copies of the
source and the test file and point you to the problem area to see it
in full context.

--Frank
27-Apr-90 18:36:12-PDT,771;000000000000
Received: from WSMR-SIMTEL20.ARMY.MIL by NIC.DDN.MIL with TCP; Fri, 27 Apr 90 18:31:10 PDT
Date: Fri, 27 Apr 1990  19:31 MDT
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: Misleading error message

When the following is compiled with -DBUG, CC complains with the wrong
error message (about the + operator).

--Frank
--------------------

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

main()
{
    char ifn[100];
    int ldate;

    ldate = 0;
    strcpy(ifn, "TEST.FIL");
    printf("Creating new files report for %d\n", (ldate+1));
#ifdef BUG
    ifn[strchr(ifn, '.')] = 0;
#endif
}
14-May-90 10:54:31-PDT,1434;000000000005
Date: Mon, 14 May 90 10:51:42 PDT
From: The Mailer Daemon <[email protected]>
To: [email protected]
Subject: Message of 9-May-90 06:55:29

Message undeliverable and dequeued after 5 days:
*fs:<c.dist>[email protected].#Internet: Disk quota exceeded
	    ------------
Received: from vera.nada.kth.se by NIC.DDN.MIL with TCP; Wed, 9 May 90 06:55:21 PDT
Date: Tue, 8 May 90 15:03:54 +0200
From: Jan Michael Rynning <[email protected]>
Subject: Bug fix for KCC-6 tadl_from_utime()
Sender: [email protected]
To: [email protected]
Reply-To: Jan Michael Rynning <[email protected]>
Organization: Royal Institute of Technology, Stockholm, Sweden.
Address: NADA, KTH, S-100 44 Stockholm, Sweden.
Telephone: +46-8-7906288
Message-ID: <[email protected]>

In KCCDIST:<KCC-6.LIB.USYS>TIME.C.87, in function tadl_from_utime():

	+ ((utad%DAYSECS)<<HBITS + DAYSECS/2)/DAYSECS	/* # units of rem */

Due to operator precendence, an extra pair of parentheses is required:

	+ (((utad%DAYSECS)<<HBITS) + DAYSECS/2)/DAYSECS	/* # units of rem */

Jan Michael Rynning,			[email protected]
Department of Numerical Analysis	If you can't fully handle domains:
  and Computing Science,		ARPA: jmr%[email protected]
Royal Institute of Technology,		UUCP: {uunet,mcvax,...}!nada.kth.se!jmr
S-100 44 Stockholm,			BITNET: jmr@sekth
Sweden.					Phone: +46-8-7906288
-------
14-May-90 10:54:34-PDT,1269;000000000005
Date: Mon, 14 May 90 10:51:43 PDT
From: The Mailer Daemon <[email protected]>
To: [email protected]
Subject: Message of 9-May-90 06:55:47

Message undeliverable and dequeued after 5 days:
*fs:<c.dist>[email protected].#Internet: Disk quota exceeded
	    ------------
Received: from vera.nada.kth.se by NIC.DDN.MIL with TCP; Wed, 9 May 90 06:55:44 PDT
Date: Tue, 8 May 90 16:01:27 +0200
From: Jan Michael Rynning <[email protected]>
Subject: BSD4.3 utimes() for KCC-6
Sender: [email protected]
To: [email protected]
Reply-To: Jan Michael Rynning <[email protected]>
Organization: Royal Institute of Technology, Stockholm, Sweden.
Address: NADA, KTH, S-100 44 Stockholm, Sweden.
Telephone: +46-8-7906288
Message-ID: <[email protected]>

/*
**	UTIMES - set file times
**
**	(c) Copyright Jan Michael Rynning 1990
*/

#include <sys/usysig.h>
#include <sys/time.h>

extern int utime();

int utimes(file, tvp)
char *file;
struct timeval tvp[2];
{
    time_t timep[2];

    USYS_BEG();
    timep[0] = tvp[0].tv_sec;			/* copy the read time */
    timep[1] = tvp[1].tv_sec;			/* copy the write time */
    USYS_RETVOLATILE(utime(file, timep));	/* let utime() do the job */
}
-------
 1-Jul-90 19:12:26-PDT,1073;000000000000
Received: from WSMR-SIMTEL20.ARMY.MIL by NIC.DDN.MIL with TCP; Sun, 1 Jul 90 19:10:27 PDT
Date: Sun, 1 Jul 1990  20:10 MDT
Message-ID: <[email protected]>
From: "Frank J. Wancho" <[email protected]>
To:   [email protected]
cc:   [email protected]
Subject: ioctl() problem

There is a tty file transfer program, written in C, that I would like
to further modify so that it will turn on raw mode only in the
direction of file transfer.  The reason is to permit flow control to
work in the opposite direction, particularly for uploads at 9600 bps.

I understand this is possible if there were two jfns used, one for
input and one for output.  However, it is not clear that the ioctl()
function will do the right thing, i.e., it appears to be treating the
controlling terminal as one jfn for both input and output.  If this is
the case, what options are open for me to try?  If not, can I simply
freopen(*ttyin, 'r8', stdin) and freopen(*ttyout, 'w', stdout) in the
case of raw input only?

--Frank
 2-Jul-90 10:19:28-PDT,985;000000000000
Mail-From: KLH created at  2-Jul-90 10:18:38
Date: Mon, 2 Jul 90 10:18:27 PDT
From: Ken Harrenstien <[email protected]>
Subject: Re: ioctl() problem
To: [email protected], [email protected]
cc: [email protected]
In-Reply-To: <[email protected]>
Message-ID: <[email protected]>

You have to realize that the KCC implementation of ioctl() tries to emulate
Un*x, where anything that mungs the terminal settings has a global effect.

I believe there are other TTY control bits besides RAW that could be
used (in a complete emulation) to do what you want.  I would suggest
(1) finding a UPM and looking at tty(4), then (2) looking at
<.lib.usys>ioctl.c to see whether and how the emulation code can be
modified, and (3) letting me know what the successful changes are.
I'm not sure whether your freopen() idea would work, since I believe
the OS bits that are currently munged are per-TTY rather than per-JFN.
-------