1 : /*
2 : ** Copyright (C) 2000 Erik de Castro Lopo <erikd AT zip DOT com DOT au>
3 : **
4 : ** This program is free software; you can redistribute it and/or modify
5 : ** it under the terms of the GNU General Public License as published by
6 : ** the Free Software Foundation; either version 2 of the License, or
7 : ** (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, write to the Free Software
16 : ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 : */
18 :
19 : /* =========================================================================
20 : ** This program actually provides the functionality which was advertised for
21 : ** listing 13.6 of the book "SAMs Teach Yourself C for Linux Programming in
22 : ** 21 days", by Erik de Castro Lopo, Brad Jones and Peter Aitken.
23 : **
24 : ** Compile this code using :
25 : **
26 : ** gcc -Wall list1306_readline.c -lreadline -o list1306_readline
27 : **
28 : ** On some systems it might be necessary to also link in the termcap
29 : ** library as follows:
30 : **
31 : ** gcc -Wall list1306_readline.c -lreadline -ltermcap -o list1306_readline
32 : **
33 : ** If neither of these two compile commands works, you may be missing the
34 : ** readline library or the header files for that library from your
35 : ** installation.
36 : **
37 : ** More information about the problem in the original code will appear on the
38 : ** web page at http://www.zip.com.au/~erikd/BOOK/faq.html as soon as its
39 : ** ready.
40 : **
41 : ** Dec 21 2000 : Version 1.0 <erikd AT zip DOT com DOT au>
42 : ** Dec 21 2000 : Version 1.1 <erikd AT zip DOT com DOT au>
43 : ** Added atexit (), and restore_terminal ().
44 : */
45 :
46 : #include <stdio.h>
47 : #include <stdlib.h>
48 : #include <unistd.h>
49 : #include <termios.h>
50 : #include <readline/readline.h>
51 :
52 : #define TERM_SILENCE_ON 1
53 : #define TERM_SILENCE_OFF 0
54 :
55 : #define TERM_STDIN 0
56 :
57 : void silence_terminal (int on) ;
58 : void restore_terminal (void) ;
59 :
60 : int main (void)
61 : { int age ;
62 : char *name, *line ;
63 :
64 : /* During the running of this program we are fiddling with the terminal
65 : ** settings. If the program terminates before restoring the settings the
66 : ** settings will be permanent.
67 : ** To avoid this we register the restore_terminal function with atexit.
68 : ** The functions registered in this way are called when the program
69 : ** exits.
70 : */
71 : atexit (restore_terminal) ;
72 :
73 : line = readline ("Enter your age : ") ;
74 : sscanf (line, "%d", &age) ;
75 :
76 : /* While we're processing data (simulated by sleep (5) below) we want
77 : ** to prevent the user from typing characters at the terminal.
78 : */
79 : silence_terminal (TERM_SILENCE_ON) ;
80 :
81 : printf ("Doing some processing here.\n") ;
82 : sleep (5) ;
83 :
84 : /* We're now ready to resume dealing with the user, so turn the
85 : ** terminal back on.
86 : */
87 : silence_terminal (TERM_SILENCE_OFF) ;
88 : name = readline ("Enter your name : ") ;
89 :
90 : /* Display the data. */
91 : printf("\nYour age is %d.\n", age);
92 : printf("Your name is %s.\n", name);
93 :
94 : return 0 ;
95 : } /* main */
96 :
97 : /* The atexit () function requires a parameter-less function so we
98 : ** create one here which simply calls silence_terminal ().
99 : */
100 : void restore_terminal (void)
101 : { silence_terminal (TERM_SILENCE_OFF) ;
102 : } /* restore_terminal */
103 :
104 : void silence_terminal (int on)
105 : { /* On first entry to this function we want to store the current
106 : ** terminal settings so they can be restored later. We do that
107 : ** by storing them in static structure. We also store a modified
108 : ** copy to use as the special terminal settings for a silent
109 : ** terminal.
110 : ** The terminal settings are stored in a termios structure
111 : ** defined in <termios.h>. They are declared static so they will
112 : ** keep their information across function calls.
113 : */
114 : static struct termios original ;
115 : static struct termios no_echo ;
116 : static int initialized = 0 ;
117 :
118 :
119 : if (! initialized)
120 : { tcgetattr (TERM_STDIN, &original) ;
121 : /* Also get a another ... */
122 : tcgetattr (TERM_STDIN, &no_echo) ;
123 : /* ... and modify it, turing of terminal charcter echoing. */
124 : no_echo.c_lflag &= (~ECHO) ;
125 : initialized = 1 ;
126 : } ;
127 :
128 : if (on)
129 : { /* Turn off terminal character echoing. */
130 : tcsetattr (TERM_STDIN, TCSANOW, &no_echo) ;
131 : }
132 : else
133 : { /* Restore original settings. */
134 : tcsetattr (TERM_STDIN, TCSANOW, &original) ;
135 : /* Flush the input buffer. */
136 : tcflush (TERM_STDIN, TCIFLUSH) ;
137 : } ;
138 :
139 : return ;
140 : } /* silence_terminal */