home *** CD-ROM | disk | FTP | other *** search
- Xref: sparky comp.unix.bsd:11134 comp.lang.c:19552
- Path: sparky!uunet!noc.near.net!hri.com!spool.mu.edu!olivea!sgigate!odin!sgihub!zola!delhi!dps
- From: dps@delhi.esd.sgi.com (D.P. Suresh)
- Newsgroups: comp.unix.bsd,comp.lang.c
- Subject: Re: a unix terminal question
- Message-ID: <uonuhjc@zola.esd.sgi.com>
- Date: 11 Jan 93 22:48:02 GMT
- References: <1iql6kINNisk@ub.d.umn.edu> <1993Jan11.215312.2080@fcom.cc.utah.edu>
- Sender: news@zola.esd.sgi.com (Net News)
- Organization: Silicon Graphics, Inc. Mountain View, CA
- Lines: 103
-
-
- In article <1993Jan11.215312.2080@fcom.cc.utah.edu>, terry@cs.weber.edu writes:
- > In article <1iql6kINNisk@ub.d.umn.edu> cbusch@ub.d.umn.edu (Chris) writes:
- > >
- > > How does one read in a character from standard input without having
- > >the program wait for the key. Basically, I want to do something like:
- > > if(kbhit()) c=getch();
- > >Except that is not standard, and I want it to work on all platforms.
- >
- > This is a bad thing to do, unless you have processing to do when characters
- > aren't present, and you do your checks relatively infrequently compared to
- > the procesing itself; otherwise, you will be in a buzz-loop and suck your
- > CPU through the floor. This is common practice under DOS where there is
- > nothing else running, but is a generally bad thing to do.
- >
- > The CORRECT way to do this: use the select() or poll() system call to
- > wait for an interval or a character to be present. Resoloution is
- > generally 1/1000th of a second; you can effect a poll by having a
- > zero-valued timeval struct (as opposed to passing (struct timeval *)NULL).
- > This will cause the behaviour you have asked for. When the select()
- > returns that there are characters available, do a read() on the descriptor
- > (otherwise, return as if the read() has returned 0 characters). It
- > should be noted that some systems are sensitive to select/read pairing,
- > and if you do this, you should have a select() call prior to every read()
- > call, regardless of whther or not you use the select information aro simply
- > read anyway.
-
- select() or poll() in itself will not get you the desired result.
- If my memory of DOS does not fail me, kbhit() is a non-blocking call.
- It just tells you *at once* whether zero or more keys are waiting for
- his/her highness to be read. To get this effect on UNIX, one should
- combine select()/poll() with putting the terminal in raw mode.
-
- If you dont put the terminal in raw mode and try select()/poll()
- then even if you press a key, select()/poll() will not detect them
- until CR is given.
-
- Here is a code sample:
-
- /* Test code for kbhit function */
- #include <stdio.h>
- #include <termio.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/time.h>
- #include <sys/file.h>
-
- kbhit()
- {
- fd_set readfds, writefds, exceptfds;
- struct timeval timeout;
- static struct termio otty, ntty;
- int ret;
-
- /* Create proper environment for select() */
- FD_ZERO( &readfds );
- FD_ZERO( &writefds );
- FD_ZERO( &exceptfds );
- FD_SET( fileno(stdin), &readfds );
-
- /* We shall specify 0.5 sec as the waiting time */
- timeout.tv_sec = 0; /* 0 seconds */
- timeout.tv_usec = 500; /* 500 microseconds */
-
- /* Put tty in raw mode */
- ioctl(fileno(stdout), TCGETA, &otty);
- ntty = otty;
- ntty.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL);
- ntty.c_lflag &= ~ICANON;
- ntty.c_lflag |= ISIG;
- ntty.c_cflag &= ~(CSIZE|PARENB);
- ntty.c_cflag |= CS8;
- ntty.c_iflag &= (ICRNL|ISTRIP);
- ntty.c_cc[VMIN] = ntty.c_cc[VTIME] = 1;
- ioctl(fileno(stderr), TCSETAW, &ntty);
-
- /* Do a select */
- ret = select( 1, &readfds, &writefds, &exceptfds, &timeout );
-
- /* Reset the tty back to its original mode */
- ioctl(fileno(stderr), TCSETAW, &otty);
-
- return( ret );
- }
-
- main()
- {
- while( !kbhit() ) {
- /* No key was hit. Do your own processing. */
- }
- printf("Hey. you hit a key.\n");
- }
-
- /* End of listing */
-
-
- WARNING:
- This feature should be used wisely. One could incur quite a lot of
- performance penalties as expressed by terry.
-
- --
- D.P.Suresh
- dps@esd.sgi.com
-