Home | History | Annotate | Download | only in sandbox
      1 /*
      2 C non-blocking keyboard input
      3 http://stackoverflow.com/questions/448944/c-non-blocking-keyboard-input
      4 */
      5 
      6 #include <stdlib.h>
      7 #include <string.h>
      8 #include <sys/select.h>
      9 #include <termios.h>
     10 #include <unistd.h>
     11 #include "getch.h"
     12 
     13 struct termios orig_termios;
     14 
     15 void reset_terminal_mode()
     16 {
     17     tcsetattr(0, TCSANOW, &orig_termios);
     18 }
     19 
     20 void set_conio_terminal_mode()
     21 {
     22     struct termios new_termios;
     23 
     24     /* take two copies - one for now, one for later */
     25     tcgetattr(0, &orig_termios);
     26     memcpy(&new_termios, &orig_termios, sizeof(new_termios));
     27 
     28     /* register cleanup handler, and set the new terminal mode */
     29     atexit(reset_terminal_mode);
     30     cfmakeraw(&new_termios);
     31     new_termios.c_oflag |= OPOST;
     32     tcsetattr(0, TCSANOW, &new_termios);
     33 }
     34 
     35 int kbhit()
     36 {
     37     struct timeval tv = { 0L, 0L };
     38     fd_set fds;
     39     FD_ZERO(&fds); // not in original posting to stackoverflow
     40     FD_SET(0, &fds);
     41     return select(1, &fds, NULL, NULL, &tv);
     42 }
     43 
     44 int getch()
     45 {
     46     int r;
     47     unsigned char c;
     48     if ((r = read(0, &c, sizeof(c))) < 0) {
     49         return r;
     50     } else {
     51         return c;
     52     }
     53 }
     54 
     55 #if 0
     56 int main(int argc, char *argv[])
     57 {
     58     set_conio_terminal_mode();
     59 
     60     while (!kbhit()) {
     61         /* do some work */
     62     }
     63     (void)getch(); /* consume the character */
     64 }
     65 #endif
     66