1 /* Noncanonical Mode Example
2    Copyright (C) 1991-2021 Free Software Foundation, Inc.
3 
4    This program is free software; you can redistribute it and/or
5    modify it under the terms of the GNU General Public License
6    as published by the Free Software Foundation; either version 2
7    of the License, or (at your option) any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, see <https://www.gnu.org/licenses/>.
16 */
17 
18 #include <unistd.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <termios.h>
22 
23 /* Use this variable to remember original terminal attributes. */
24 
25 struct termios saved_attributes;
26 
27 void
reset_input_mode(void)28 reset_input_mode (void)
29 {
30   tcsetattr (STDIN_FILENO, TCSANOW, &saved_attributes);
31 }
32 
33 void
set_input_mode(void)34 set_input_mode (void)
35 {
36   struct termios tattr;
37   char *name;
38 
39   /* Make sure stdin is a terminal. */
40   if (!isatty (STDIN_FILENO))
41     {
42       fprintf (stderr, "Not a terminal.\n");
43       exit (EXIT_FAILURE);
44     }
45 
46   /* Save the terminal attributes so we can restore them later. */
47   tcgetattr (STDIN_FILENO, &saved_attributes);
48   atexit (reset_input_mode);
49 
50 /*@group*/
51   /* Set the funny terminal modes. */
52   tcgetattr (STDIN_FILENO, &tattr);
53   tattr.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO.  */
54   tattr.c_cc[VMIN] = 1;
55   tattr.c_cc[VTIME] = 0;
56   tcsetattr (STDIN_FILENO, TCSAFLUSH, &tattr);
57 }
58 /*@end group*/
59 
60 int
main(void)61 main (void)
62 {
63   char c;
64 
65   set_input_mode ();
66 
67   while (1)
68     {
69       read (STDIN_FILENO, &c, 1);
70       if (c == '\004')		/* @kbd{C-d} */
71 	break;
72       else
73 	putchar (c);
74     }
75 
76   return EXIT_SUCCESS;
77 }
78