/* ** Copyright (C) 2000 Erik de Castro Lopo ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* ========================================================================= ** This program actually provides the functionality which was advertised for ** listing 13.6 of the book "SAMs Teach Yourself C for Linux Programming in ** 21 days", by Erik de Castro Lopo, Brad Jones and Peter Aitken. ** ** Compile this code using : ** ** gcc -Wall list1306_readline.c -lreadline -o list1306_readline ** ** On some systems it might be necessary to also link in the termcap ** library as follows: ** ** gcc -Wall list1306_readline.c -lreadline -ltermcap -o list1306_readline ** ** If neither of these two compile commands works, you may be missing the ** readline library or the header files for that library from your ** installation. ** ** More information about the problem in the original code will appear on the ** web page at http://www.zip.com.au/~erikd/BOOK/faq.html as soon as its ** ready. ** ** Dec 21 2000 : Version 1.0 ** Dec 21 2000 : Version 1.1 ** Added atexit (), and restore_terminal (). */ #include #include #include #include #include #define TERM_SILENCE_ON 1 #define TERM_SILENCE_OFF 0 #define TERM_STDIN 0 void silence_terminal (int on) ; void restore_terminal (void) ; int main (void) { int age ; char *name, *line ; /* During the running of this program we are fiddling with the terminal ** settings. If the program terminates before restoring the settings the ** settings will be permanent. ** To avoid this we register the restore_terminal function with atexit. ** The functions registered in this way are called when the program ** exits. */ atexit (restore_terminal) ; line = readline ("Enter your age : ") ; sscanf (line, "%d", &age) ; /* While we're processing data (simulated by sleep (5) below) we want ** to prevent the user from typing characters at the terminal. */ silence_terminal (TERM_SILENCE_ON) ; printf ("Doing some processing here.\n") ; sleep (5) ; /* We're now ready to resume dealing with the user, so turn the ** terminal back on. */ silence_terminal (TERM_SILENCE_OFF) ; name = readline ("Enter your name : ") ; /* Display the data. */ printf("\nYour age is %d.\n", age); printf("Your name is %s.\n", name); return 0 ; } /* main */ /* The atexit () function requires a parameter-less function so we ** create one here which simply calls silence_terminal (). */ void restore_terminal (void) { silence_terminal (TERM_SILENCE_OFF) ; } /* restore_terminal */ void silence_terminal (int on) { /* On first entry to this function we want to store the current ** terminal settings so they can be restored later. We do that ** by storing them in static structure. We also store a modified ** copy to use as the special terminal settings for a silent ** terminal. ** The terminal settings are stored in a termios structure ** defined in . They are declared static so they will ** keep their information across function calls. */ static struct termios original ; static struct termios no_echo ; static int initialized = 0 ; if (! initialized) { tcgetattr (TERM_STDIN, &original) ; /* Also get a another ... */ tcgetattr (TERM_STDIN, &no_echo) ; /* ... and modify it, turing of terminal charcter echoing. */ no_echo.c_lflag &= (~ECHO) ; initialized = 1 ; } ; if (on) { /* Turn off terminal character echoing. */ tcsetattr (TERM_STDIN, TCSANOW, &no_echo) ; } else { /* Restore original settings. */ tcsetattr (TERM_STDIN, TCSANOW, &original) ; /* Flush the input buffer. */ tcflush (TERM_STDIN, TCIFLUSH) ; } ; return ; } /* silence_terminal */