Установка данного флага включает канонический режим ввода. Ввод группируется по строкам, а символы EOF, EOL, EOL2, ERASE, LNEXT, KILL, REPRINT и WERASE интерпретируются особым образом (обратите внимание на влияние флага IEXTEN).
Установка данного флага включает расширенную обработку вводимых символов. Он (равно как и ICANON) требуется для интерпретации следующих символов: EOL2, LNEXT, REPRINT и WERASE. Кроме того, без него не работает флаг IUCLC. В стандарте SUSv3 всего лишь указано, что флаг IEXTEN включает расширенные функции; детали могут варьироваться в зависимости от реализации.
В Linux установка данного флага игнорируется. В консоли при заполнении входящей очереди всегда срабатывает звуковой сигнал.
Установка этого флага включает режим с обработкой (англ. cooked mode; см. подраздел 58.6.3), позволяющий корректно интерпретировать ввод символов UTF-8 при редактировании строки.
По умолчанию, когда при вводе символов INTR, QUIT или SUSP генерируется сигнал, любые дополнительные данные во входящей и исходящей очередях терминала сбрасываются (отклоняются). Во избежание этого устанавливается флаг NOFLSH.
Данный флаг включает постобработку вывода. Его наличие требуется для работы любых флагов в поле c_oflag структуры termios (и наоборот — сброс флага OPOST предотвращает любую постобработку вывода).
Эти флаги относятся к генерированию и проверке соответствия.
Флаг PARENB включает генерирование битов, которые используются для проверки соответствия выводимых и вводимых символов. Если интересует только соответствие выводимых символов, то можно отключить проверку ввода, сбросив флаг INPCK. Сброс и установка флага PARODD делают проверку соответствия четной и нечетной соответственно.
Остальные флаги определяют то, как именно будут обрабатываться вводимые символы с ошибками соответствия. При установленном флаге IGNPAR символ отклоняется (не передается считывающему процессу). В противном случае, если установлен флаг PARMRK, то символ доходит до считывающего процесса, но содержит в начале двухбайтовую последовательность 0377 + 0 (когда флаг PARMRK установлен, а ISTRIP сброшен, настоящий символ с кодом 0377 дублируется и превращается в 0377 + 0377). Если флаг PARMRK сброшен, а INPCK установлен, то символ отклоняется, а считывающему процессу передается нулевой байт. Когда сброшены все три флага, IGNPAR, PARMRK и INPCK, символ передается процессу в исходном виде.
В листинге 58.2 демонстрируется применение функций tcgetattr() и tcsetattr() для выключения флага ECHO, чтобы вводимые символы не отображались на экране. Ниже показан пример того, что можно увидеть при запуске данной программы:
$ ./no_echo
Enter text:
Read: Knock, knock, Neo.
Листинг 58.2. Отключение эхо-контроля в терминале
tty/no_echo.c
#include
#include "tlpi_hdr.h"
#define BUF_SIZE 100
int
main(int argc, char *argv[])
{
struct termios tp, save;
char buf[BUF_SIZE];
/* Получаем текущие параметры терминала, выключаем эхо-контроль */
if (tcgetattr(STDIN_FILENO, &tp) == -1)
errExit("tcgetattr");
save = tp; /* Позже это позволит восстановить параметры */
tp.c_lflag &= ~ECHO; /* Сбрасываем флаг ECHO, остальные биты не трогаем */
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &tp) == -1)
errExit("tcsetattr");
/* Считываем ввод и отображаем его на экране */
printf("Enter text: ");
fflush(stdout);
if (fgets(buf, BUF_SIZE, stdin) == NULL)
printf("Got end-of-file/error on fgets()\n");
else
printf("\nRead: %s", buf);
/* Восстанавливаем исходные параметры терминала */
if (tcsetattr(STDIN_FILENO, TCSANOW, &save) == -1)
errExit("tcsetattr");
exit(EXIT_SUCCESS);
}
tty/no_echo.c
Мы уже отмечали, что драйвер терминала способен обрабатывать ввод в каноническом и неканоническом режимах в зависимости от того, установлен ли флаг ICANON. Теперь остановимся на этом более подробно, после чего познакомимся с тремя дополнительными режимами — с обработкой, без обработки и cbreak, которые стали доступными в седьмой редакции системы UNIX. Мы покажем, как указанные режимы эмулируются в современных системах путем установки соответствующих значений в структуре termios.
58.6.1. Канонический режим
Данный режим ввода включается путем установки флага ICANON. Терминальный ввод в каноническом режиме имеет следующие отличительные черты.
• Ввод группируется в строки, в конце каждой из которых находится символ-разделитель: NL, EOL, EOL2 (если установлен флаг IEXTEN), EOF (если только курсор находится не в начале строки) или CR (при установленном флаге ICRNL). Любые разделители, кроме EOF, передаются считывающему процессу (в качестве последнего символа строки).