/* Extremely inefficient but portable POSIX getch() */ #include #include #include /* for tcgetattr() and tcsetattr() */ #include /* for read() */ #include #include #include #include "getch.h" #ifndef STDIN_FILENO # define STDIN_FILENO 0 #endif int getch (void) { struct termios save_termios; struct termios ios; int c = 0; if (!isatty (STDIN_FILENO)) return EOF; if (tcgetattr (STDIN_FILENO, &save_termios) < 0) return EOF; ios = save_termios; ios.c_lflag &= ~(ICANON | ECHO | ISIG); ios.c_cc[VMIN] = 1; /* read() will return with one char */ ios.c_cc[VTIME] = 0; /* read() blocks forever */ if (tcsetattr (STDIN_FILENO, TCSANOW, &ios) < 0) return EOF; if (read (STDIN_FILENO, &c, 1) != 1) c = EOF; tcsetattr (STDIN_FILENO, TCSANOW, &save_termios); return c; } int kbhit (void) { struct termios save_termios; struct termios ios; fd_set inp; struct timeval timeout = {0, 0}; int result; if (!isatty (STDIN_FILENO)) return 0; if (tcgetattr (STDIN_FILENO, &save_termios) < 0) return 0; ios = save_termios; ios.c_lflag &= ~(ICANON | ECHO | ISIG); ios.c_cc[VMIN] = 1; /* read() will return with one char */ ios.c_cc[VTIME] = 0; /* read() blocks forever */ if (tcsetattr (STDIN_FILENO, TCSANOW, &ios) < 0) return 0; /* set up select() args */ FD_ZERO(&inp); FD_SET(STDIN_FILENO, &inp); result = select (STDIN_FILENO+1, &inp, NULL, NULL, &timeout) == 1; tcsetattr (STDIN_FILENO, TCSANOW, &save_termios); return result; } #if defined TEST_GETCH int main () { int i; char c[4]; printf("Enter %d keys to continue: ", sizeof c - 1); fflush (stdout); memset(c, 0, sizeof c); for (i=0; i