[net.sources] Bug in life.c and hidden gotcha in dpy

clewis@mnetor.UUCP (Chris Lewis) (04/15/85)

Problem with life.c on Pyramid (BSD universe):
in file io.c, the following function appears:

/*
 * Read next character from the terminal if it is ready.  If nothing is
 * going on we will wait for it anyway, to prevent excessive runtimes.
 * We set the interactive flag to indicate we are talking to user.
 */
tty_char()
{
	long	n;			/* char count */
	int	ch;			/* char to return */
#ifdef	pyr
	char	char_k;
#endif

	interact = 1;
	if ((dowait == 0) && (redraw || update || (genleft > 0))) {
		if ((ioctl(STDIN, FIONREAD, &n) == 0) && (n <= 0)) {
			scaneof();		/* no char available now */
		}
	}
	do {
		if (stop) return('\0');		/* stop will be seen later */
		errno = 0;
#ifdef	pyr		/* ARG!!!!!! */
		n = read(STDIN, &char_k, 1);	/* read one char */
		ch = char_k;
#else
		n = read(STDIN, &ch, 1);	/* read one char */
#endif
	} while ((n < 0) && (errno == EINTR));
	if (n <= 0) {
		return(-1);			/* error or end of file */
	}
	if (errorstring) {			/* disable error message */
		errorstring = NULL;
		update = 1;
	}
	return(ch &= 0x7f);
}

I inserted the ifdef pyr.  The original code "n = read(STDIN, &ch, 1)" assumed
VAX byteorder.  (eg: msb first).  This is obviously not the case with
many other machines (m68k, Pyramid etc.).  I used an ifdef because I wanted
to keep the sources as close to the original as possible.  A proper
fix would be to have "ch" a "char".

Another hidden gotcha is the definition of "dpyprintf" in the dpy module
"dpy.c".  This is the traditional "varargs" problem.  The original
solution (ifdef BSD) was to use the traditional V7 pdp11 trick to
get the arguments to dpyprintf to _doprnt by just declaring two arguments,
the address of the last argument passed to _doprnt.  The USG variant works
fine even in the Pyramid BSD variant (properly using varargs).
Thank god SVR2 documents _doprnt (or whatever they called it).
-- 
Chris Lewis, Computer X (CANADA) Ltd.
UUCP: {allegra, linus, ihnp4}!utzoo!mnetor!clewis
BELL: (416)-475-1300 ext. 321