Эта программа может служить в качестве клавиатурного тренажера и является примером неканонического ввода. Она выводит на экран строку текста, и пользователь должен напечатать ее. Символы по мере ввода проверяются. Если введен неправильный символ, программа издает звуковой сигнал и печатает звездочку. Если введен правильный символ, он выводится на экран. Программа работает так:
15-20 Терминальный специальный файл открывается для чтения, и его текущий режим записывается в структуру termios. Библиотечная функция isatty(3F) проверяет, связан ли файловый дескриптор 1 с терминалом. Иными словами, эта программа не должна исполняться с использованием перенаправления стандартного ввода/вывода shell. Функция isatty описана на странице руководства ttyname(3F).
22-24 Терминальный интерфейс переводится в режим неканонического ввода без эхо и без обработки специальных символов.
25 Вызовом стандартной библиотечной функции setbuf(3) запрещается локальная буферизация в библиотечных функциях вывода. Это приводит к тому, что putchar(3) в следующих строках будет немедленно вызывать write(2) в стандартный вывод.
28-37 Этот цикл читает по одному символу и сравнивает его с соответствующим символом строки text. Если символ введен правильно, он немедленно выводится на терминал. Иначе издается звуковой сигнал и на терминал выводится звездочка.
Ниже приведен пример работы программы:
$ typtut
Type in beneath the following line
The quick brown fox jumped over the lazy dog's back
The *uick b*own f** jumped over t*e lazy dog's back
number of errors: 5
Файл: typtut.c
КЛАВИАТУРНЫЙ ТРЕНАЖЕР - ПРИМЕР НЕКАНОНИЧЕСКОГО ВВОДА
1 #include <unistd.h>
2 #include <stdio.h>
3 #include <fcntl.h>
4 #include <termios.h>
5 #include <string.h>
6 #include <stdlib.h>
8 main()
9 {
10 char ch, *text =
11 "The quick brown fox jumped over the lazy dog\'s back";
12 int fd, i, errors = 0, len;
13 struct termios tty, savtty;
15 fd = open("/dev/tty", O_RDONLY);
16 tcgetattr(fd, &tty);
17 if (isatty(fileno(stdout)) == 0) {
18 fprintf(stderr,"stdout not terminal\n");
19 exit(1);
20 }
21 savtty = tty;
22 tty.c_lflag &= ~(ISIG | ICANON | ECHO);
23 tty.c_cc[VMIN] = 1; /* MIN */
24 tcsetattr(fd, TCSAFLUSH, &tty);
25 setbuf(stdout, (char *) NULL);
26 printf("Type beneath the following line\n\n%s\n", text);