Return to BSD News archive
Received: by minnie.vk1xwt.ampr.org with NNTP id AA5762 ; Fri, 01 Jan 93 01:55:04 EST Xref: sserve comp.unix.bsd:9490 comp.unix.programmer:7715 Newsgroups: comp.unix.bsd,comp.unix.programmer Path: sserve!manuel.anu.edu.au!munnari.oz.au!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