[net.unix-wizards] Keyboard check under UNIX Sys V?

sbw@arizona.UUCP (stephen wampler) (09/25/86)

What is the preferred way to determine if a key has been pressed
on the keyboard when running UNIX Sys V?  I know that some UN*X
versions have ioctl()s for checking the input queue size (in
some cases the ioctl() is undocumented), but I don't see anything
like that in Sys V.

Please mail responses back to me.  I rarely reach the net.

	Thanks in advance!
	Steve Wampler

	{ucbvax, ihnp4, etc...}!arizona!naucse!sbw

stuart@BMS-AT.UUCP (Stuart D. Gathman) (09/28/86)

In article <30896@arizona.UUCP>, sbw@arizona.UUCP (stephen wampler) writes:
> What is the preferred way to determine if a key has been pressed
> on the keyboard when running UNIX Sys V?  I know that some UN*X

#include <sys/termio.h>

{
  struct termio tty, save;
  char c;

  ioctl(0,TCGETA,&tty);
  save = tty;				/* save current tty definitions */
  tty.c_lflag &= ~(ECHO|ICANON);	/* enter raw mode */
  tty.c_cc[VMIN]=0;		/* wait for at least VMIN chars on read */
  tty.c_cc[VTIME]=0;		/* wait at least VTIME seconds/10 on read */
  ioctl(0,TCSETA,&tty);

  saved = read(0,&c,1);
  if (saved)
    printf("You typed a '%c'.\n",c);
  else
    printf("You haven't typed anything yet.\n");

/*
  Note, you will have to save 'c' yourself if you need it!
  Perhaps stdio would work (using ungetc()).
*/

/* restore tty state */

  ioctl(0,TCSETA,&save);
}
-- 
Stuart D. Gathman	<..!seismo!{vrdxhq|dgis}!BMS-AT!stuart>

jeff@cdp.UUCP (09/30/86)

i'm not sure if i agree that using VMIN/VTIME and raw mode is
the "preferred" way of doing unblocked reads, but it is one way.
your preference may depend on your application.  in the applications
i've done, i prefer to use O_NDELAY.  anyway, here are a few
issues you might want to consider:

- if you use "raw" mode, this means that your application must
provide its own erase and kill handling.
- a note on ungetc: you cannot ungetc something before you do a
(buffered) stdio read from the input stream.  this is documented
in the manual page, although in practice, not all systems are
this strict.
- an alternative to ungetc is to maintain a one character lookahead
buffer.  if you have one central input routine, then this change
is easy to pop into place.  if you use many different input routines,
then you have more work on your hands.
- the alternative approach is to open the input stream with
O_NDELAY.  however, since you probably don't want unblocked
reads all the time, a convenient hack is to open up a separate
descriptor for stdin with O_NDELAY, and use that descriptor
only for readahead.

if this sounds unnecessarily complicated, that's because it is.
the berkeley users have FIONREAD, which is much nicer...

SofPasuk@imagen.UUCP (Munach Rvi'i) (10/02/86)

> In article <30896@arizona.UUCP>, sbw@arizona.UUCP (stephen wampler) writes:
> > What is the preferred way to determine if a key has been pressed
> > on the keyboard when running UNIX Sys V?  I know that some UN*X
> 
> #include <sys/termio.h>
> 
> {
>   struct termio tty, save;
>   char c;
> 
>   ioctl(0,TCGETA,&tty);
>   save = tty;				/* save current tty definitions */
>   tty.c_lflag &= ~(ECHO|ICANON);	/* enter raw mode */
>   tty.c_cc[VMIN]=0;		/* wait for at least VMIN chars on read */
>   tty.c_cc[VTIME]=0;		/* wait at least VTIME seconds/10 on read */
>   ioctl(0,TCSETA,&tty);
> 
>   saved = read(0,&c,1);
>   if (saved)
>     printf("You typed a '%c'.\n",c);
>   else
>     printf("You haven't typed anything yet.\n");
> 
> /*
>   Note, you will have to save 'c' yourself if you need it!
>   Perhaps stdio would work (using ungetc()).
> */
> 
> /* restore tty state */
> 
>   ioctl(0,TCSETA,&save);
> }
> -- 
> Stuart D. Gathman	<..!seismo!{vrdxhq|dgis}!BMS-AT!stuart>

Don't assume that this works for all System V UNIX implementations.
For example, Convergent Technologies CTIX on MegaFrame and MiniFrame will block
on the read!

guy@sun.uucp (Guy Harris) (10/02/86)

> > > What is the preferred way to determine if a key has been pressed
> > > on the keyboard when running UNIX Sys V? ...
> >   ...
> >   tty.c_cc[VMIN]=0;		/* wait for at least VMIN chars on read */
> >   tty.c_cc[VTIME]=0;	/* wait at least VTIME seconds/10 on read */
> >   ioctl(0,TCSETA,&tty);
> > 
> >   saved = read(0,&c,1);
> >   ...
> 
> Don't assume that this works for all System V UNIX implementations.
> For example, Convergent Technologies CTIX on MegaFrame and MiniFrame will
> block on the read!

Somebody else claimed that the behavior of the tty driver under some
circumstances, probably those with a MIN of 0, changed between S5R1 and
S5R2.  I don't know what version the CTIX you tried this on was based on,
but the CTIX on the UNIX PC is alleged to be based mostly on S5R1.

However, I happen to have the VAX sources for S5R1 and S5R2 (Version 1)
handy (thank you, NFS), so I "diff"ed "/usr/src/uts/vax/io/tt1.c" and
"/usr/src/uts/vax/io/tty.c" between S5R1 and S5R2.  Lo and behold, the
*only* difference between the two "tty.c" versions is the SCCS ID, and the
only non-trivial differences between the two "tt1.c" versions are 1) the
addition of the SWTCH character for shell layers and 2) the addition of some
code to handle breaks a little differently.

If somebody has evidence that S5R1 and S5R2 differ in the handling of
MIN == 0 cases on *vanilla* S5 distributions (i.e., nobody made any changes
to "tty.c" or "tt1.c"), I'd like to hear it.  Otherwise, the differences are
probably a function of somebody "fixing" their S5 to work the way S3 did.
In S3, TIME was *never* a timeout whose clock started when the read was
performed; the clock started only when a character arrived.

Note that the SVID goes into some detail about the expected behavior for
different cases of MIN, TIME, or both equal to zero, so if the read blocks
in the above circumstance the system isn't SVID-compliant.
-- 
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com (or guy@sun.arpa)

grr@cbmvax.cbm.UUCP (George Robbins) (10/04/86)

In article <7847@sun.uucp> guy@sun.uucp (Guy Harris) writes:
>If somebody has evidence that S5R1 and S5R2 differ in the handling of
>MIN == 0 cases on *vanilla* S5 distributions (i.e., nobody made any changes
>to "tty.c" or "tt1.c"), I'd like to hear it.  Otherwise, the differences are
>probably a function of somebody "fixing" their S5 to work the way S3 did.
>In S3, TIME was *never* a timeout whose clock started when the read was
>performed; the clock started only when a character arrived.
>	Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy

I believe that the was a problem with the documentation for System III not
matching the semantics actually implemented in the 'real' System III.  Zilog
stumbled badly on this when they changed their tty driver to conform to the
manual between System III releases, and wouldn't change it back.  Then they
had to flip-flop again when they went to do a System V port.

I wouldn't be at all suprising for any of the early System V ports to actually
be using updated System III tty drivers, rather then starting from scratch.

At least unix isn't alone in this madness:  there are a lot of IBM 2780/3780
emulations that choke stiff on a missing block, becuase the IBM Bisync GI manual
gives an incorrect description of what to do on a block sequence error.

-- 
George Robbins - now working for,	uucp: {ihnp4|seismo|caip}!cbmvax!grr
but no way officially representing	arpa: cbmvax!grr@seismo.css.GOV
Commodore, Engineering Department	fone: 215-431-9255 (only by moonlite)

stuart@BMS-AT.UUCP (Stuart D. Gathman) (10/08/86)

In article <592@imagen.UUCP>, SofPasuk@imagen.UUCP (Munach Rvi'i) writes:

> Don't assume that this works for all System V UNIX implementations.
> For example, Convergent Technologies CTIX on MegaFrame and MiniFrame ...

Funny, it works on *our* CTIX MiniFrame!
-- 
Stuart D. Gathman	<..!seismo!{vrdxhq|dgis}!BMS-AT!stuart>

stu@jpusa1.UUCP (Stu Heiss) (10/08/86)

Summary:

Expires:


In article <7847@sun.uucp> guy@sun.uucp (Guy Harris) writes:
-> > > What is the preferred way to determine if a key has been pressed
-> > > on the keyboard when running UNIX Sys V? ...
-Note that the SVID goes into some detail about the expected behavior for
-different cases of MIN, TIME, or both equal to zero, so if the read blocks
-in the above circumstance the system isn't SVID-compliant.

How about someone in the know clarifying the behavior for the various
combinations of MIN and TIME for those of us who don't have easy access
to SVID?  This has always been a confusing issue...
-- 
Stu Heiss {ihnp4!jpusa1!stu}