getch.c 1.3 KB

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