home *** CD-ROM | disk | FTP | other *** search
- Xref: sparky comp.unix.bsd:10772 comp.unix.programmer:5801
- Newsgroups: comp.unix.bsd,comp.unix.programmer
- Path: sparky!uunet!paladin.american.edu!gatech!emory!swrinde!elroy.jpl.nasa.gov!ames!pacbell.com!UB.com!quack!dfox
- From: dfox@quack.sac.ca.us (David Fox)
- Subject: 386bsd: how to read characters non-blocking
- Message-ID: <fXiL7vY@quack.sac.ca.us>
- Followup-To: comp.unix.bsd
- Keywords: termios, kbhit(), non-blocking read
- Organization: The Duck Pond public unix: +1 408 249 9630, log in as 'guest'.
- Date: 30 Dec 1992 20:31:09 UTC
- Lines: 101
-
- Hi *,
-
- I've had some problems recently trying to emulate the MS-DOS function
- kbhit() in 386BSD. I've gotten some good help, but the functions I've
- tried don't work the way I think they're supposed to. In MS-DOS, a
- kbhit() simply returns (with a zero result) if no key has been pressed,
- enabling the rest of the program (usually, a while loop) to continue
- processing. That's what I want to do - loop until a key has been
- pressed. However, the functions that I've tried so far (termios, stty,
- read, cbreak, etc.) only emulate the getch() function which sits there until
- a key has been pressed, which doesn't allow my program to continue
- processing.
-
- Why I've decided to post is because I received some example code that
- uses the BSD termio and sets up for a non-blocking read (which is
- apparently what I want). This produces the expected behavior when
- run on a Sparc (the site I use for mail/news) - it continues processing
- in the loop, returning immediately if no key has been pressed. After
- editing this to make it compile under 386BSD (taking into account that
- termio should be termios) it doesn't work the same way. It simply sits
- there in the kbhit() function until I press a key.
-
- --- Begin sample code ---
-
- #include <stdio.h>
- #include <sys/types.h>
- #include <termio.h>
-
- main()
- {
- int ch;
-
- for (;;) {
- if ((ch = kbhit()) != 0)
- printf("a key was hit (%d)\n", ch);
- if (ch == 3)
- break;
- printf(".");
- fflush(stdout);
- }
- }
-
- /*
- * return a non-zero value if a key has been pressed (the value returned
- * is the ascii value of the key); note that this function does not do
- * anything special with multibyte sequences (such as those returned by
- * function keys or cursor motion keys)
- */
- int
- kbhit()
- {
- struct termio old, new; /* I changed to struct termios */
- int retval;
- char ch;
-
- /*
- * get the line settings for standard input and save them
- * in ``old''; we also copy them to ``new'' so that we can
- * change the settings appropriately
- */
- ioctl(0, TCGETA, &old); /* changed to TIOCGETA */
- memcpy((char *)&new, (char *)&old, sizeof(struct termio));
- /* changed termio to termios */
- /*
- * set ``raw'' mode, ignore breaks, don't post-process output,
- * don't echo characters, etc.
- */
- new.c_iflag |= IGNBRK;
- new.c_oflag &= ~OPOST;
- new.c_lflag &= ~(ISIG|ICANON|ECHO);
- new.c_cc[VMIN] = 0;
- new.c_cc[VTIME] = 1;
-
- /*
- * change the terminal line settings, read a character and
- * then restore the terminal back to it's original state
- */
- ioctl(0, TCSETA, &new); /* changed to TIOCSETA */
- retval = read(0, &ch, 1);
- ioctl(0, TCSETA, &old); /* changed to TIOCSETA */
-
- /*
- * ``retval'' will either contain 1 (which means a key was
- * pressed), 0 (which means that no key was pressed), or -1
- * (which means an error occurred, check errno)
- */
- if (retval > 0)
- retval = (int)ch;
-
- return retval;
- }
-
- ---- End of included code ----
-
- Forgive my ignorance, I am not yet well-skilled in Unix C programming,
- but I'm fairly familiar with DOS C programming.
-
- --
- David Fox
- dfox@quack.sac.ca.us
-
-