Основы программирования в Linux - Страница 88
Для установки атрибутов применяется действие
TCSAFLUSHДругой распространенный пример использования структуры
termiosMINTIMEПрименяя только что полученные знания, вы можете изменить программу menu. Приведенная далее программа menu4.c базируется на программе menu3.c и использует большую часть кода из файла password.с, включенного в нее. Внесенные изменения выделены цветом и объясняются в пунктах описания.
1. Прежде всего, вам следует, включить новый заголовочный файл в начало программы:
#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <termios.h>char *menu[] = { "a — add new record", "d — delete record", "q - quit", NULL,};2. Затем нужно объявить пару новых переменных в функции
mainint getchoice(char *greet, char *choices[], FILE *in, FILE *out);int main() { int choice = 0; FILE *input; FILE *output; struct termios initial_settengs, new_settings;3. Перед вызовом функции
getchoice if (!isatty(fileno(stdout))) { fprintf(stderr, "You are not a terminal, OK.n"); } input = fopen("/dev/tty", "r"); output = fopen("/dev/tty", "w"); if (!input || !output) { fprintf(stderr, "Unable to open /dev/ttyn"); exit(1); } tcgetattr(fileno(input), &initial_settings); new_settings = initial_settings; new_settings.c_lfag &= ~ICANON; new_settings.c_lflag &= ~ECHO; new_settings.c_cc[VMIN] = 1; new_settings.c_cc[VTIME] = 0; new_settings.c_lflag &= ~ISIG; if (tcsetattr(fileno(input), TCSANOW, &new_settings) != 0) { fprintf(stderr, "could not set attributesn"); }4. Перед завершением вы также должны вернуть первоначальные значения:
do { choice = getchoice("Please select an action", menu, input, output); printf("You have chosen: %cn", choice); } while (choice != 'q'); tcsetattr(fileno(input), TCSANOW, &initial_settings); exit(0);}5. Теперь, когда вы в неканоническом режиме, необходимо проверить на соответствие возвраты каретки, поскольку стандартное преобразование CR (возврат каретки) в LF (переход на новую строку) больше не выполняется:
int getchoice (char *greet, char *choices[], FILE *in, FILE *out) { int chosen = 0; int selected; char **option; do { fprintf(out, "Choice: %sn", greet); option = choices; while (*option) { fprintf(but, "%sn", *option); option++; } do { selected = fgetc(in); } while (selected == 'n' || selected == 'r'); option = choices; while (*option) { if (selected == *option[0]) { chosen = 1; break; } option++; } if (!chosen) { fprintf(out, "Incorrect choice, select againn"); } } while(!chosen); return selected;}Пока вы не устроите все иначе, теперь, если пользователь нажмет в вашей программе комбинацию клавиш ISIGmain
new_settings.c_lflag &= ~ISIG;Если вы внесете эти изменения в вашу программу меню, то будете получать немедленный отклик, и вводимый вами символ не будет отображаться на экране.