Advertisement
ptkrisada

getch

Feb 29th, 2020
161
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.70 KB | None | 0 0
  1. /****************************************************************
  2.  * getch() implementation                                       *
  3.  * On windows, we have getch() in <conio.h> to get a char from  *
  4.  * keyboard without echoing it out to stdout. But Unix has no   *
  5.  * <conio.h>, it is not standard though. If we want to use      *
  6.  * getch() on Unix, we have to implement it by ourselves.       *
  7.  * As <termios.h> is defined in POSIX.1 standard, the code will *
  8.  * be portable and be able to port to ANY Unix-like systems     *
  9.  * e.g. Linux, mac, BSD, Solarix, HP-UX, AIX, IRIX, etc.        *
  10.  * without any changes in source code.                          *
  11.  ****************************************************************/
  12.  
  13. #include <unistd.h>     /* STDIN_FILENO */
  14. #include <termios.h>    /* tcgetattr(3), tcsetattr(3) */
  15. #include <stdio.h>
  16. #include <stdlib.h>     /* exit(3) */
  17.  
  18. int getch(void);        /* Prototype */
  19.  
  20. int main(void)
  21. {
  22.     char c; /* Local variable */
  23.  
  24.     printf("Starting getch(), press space to quit.\n");
  25.     while ((c = (int)getch()) != 0x20)  /* Invoke our getch().  */
  26.         printf("You type %c.\n", c);
  27.         /* Once you type a key, it will not be echoed on stdout *
  28.          * directly. It is our choice whether we want to print  *
  29.          * it out or not. We prefer to  printing the sentence   *
  30.          * mentioning what key you have typed.  */
  31.  
  32.     return 0;
  33. }
  34.  
  35. int getch(void)         /* Implementation */
  36. {
  37.     int c; /* Local variable */
  38.     struct termios oldt, newt; /* Declare old and new terminal. */
  39.  
  40.     /* Get attribute of stdin and store it in "oldt". */
  41.     if (tcgetattr(STDIN_FILENO, &oldt) != 0) {
  42.         fprintf(stderr, "tcgetattr error\n");
  43.         exit(EXIT_FAILURE);
  44.     }
  45.  
  46.     /* Copy "oldt" to "newt" */
  47.     newt = oldt;
  48.  
  49.     /* Bitwise-and to turn of canonical mode (ICANON) and echo.*/
  50.     newt.c_lflag &= ~(ICANON | ECHO);
  51.  
  52.     /* newt.c_cc[VTIME] == 0, so the time is not significant.   *
  53.      * Only newt.c_cc[VMIN] is significant.                     *
  54.      * The read is satisfied when VMIN byte(s), 1 for this case *
  55.      * is received. That is it waits for one byte input, within *
  56.      * indefinite time. Read termios(4) for more information.   */
  57.     newt.c_cc[VMIN] = 1;
  58.     newt.c_cc[VTIME] = 0;
  59.  
  60.     /* Set attribute to "newt", and take effect immediately. */
  61.     if (tcsetattr(STDIN_FILENO, TCSANOW, &newt) != 0) {
  62.         fprintf(stderr, "tcsetattr error\n");
  63.         exit(EXIT_FAILURE);
  64.     }
  65.  
  66.     /* Since we disabled ECHO and we take input char by char    *
  67.      * not canonical (line by line). getchar() will request for *
  68.      * input from a terminal. But now it will not be echoed.    */
  69.     c = getchar();
  70.  
  71.     /* Restore "oldt" prior to ending the function. */
  72.     tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
  73.  
  74.     return c; /* return a char we have read, but not echod. */
  75. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement