RESULTS: How to write keypressed()?

Chris Torek chris at mimsy.UUCP
Thu Oct 6 19:50:49 AEST 1988


In article <317 at telesoft.UUCP> jjh at telesoft.UUCP (Jim Hayes @dance) writes:
>I finally got a function that seems to work:
[bits deleted]
>  longjmp(program_state, 1);
[more deleted]
>      alarm(1);
>      a_char = getc(stdin);
>      alarm(0);
>      ungetc(a_char, stdin);

Alas, this routine has a small window during which it may eat input.
Suppose you set the alarm, and .98 seconds pass.  Then the user types
something, read() returns 1, getc() passes back the character, and
your code is about to assign a_char, when *RING* the alarm expires
and the thing jumps out.  The character has been read; it is gone.

Worse, the routine has a smaller window during which it can goof up
stdio's data structures.  `getc' maps more or less to --cnt >=0 ? *p++
:  function_call(); if the machine is heavily loaded, you might get the
`--cnt' done but nothing else, when the alarm expires, or you might be
inside function_call, with cnt reset but the pointer unchanged, or any
similar situation.

I would probably cheat, myself:

	fd_set in;
	struct timeval tv;
-->	if (stdin->_cnt != 0) return (1);	/* stuff buffered in stdio */
	FD_ZERO(&in); FD_SET(0, &in);
	tv.tv_sec = <seconds>; tv.tv_usec = <microseconds>;
	return (select(1, &in, (fd_set *)0, (fd_set *)0, &tv) == 1);

The line with the arrow is the cheat.  The select() can be a poll()
in SysVR<unreleased>.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris at mimsy.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.unix.wizards mailing list