Терминал имеет две очереди ввода и одна - вывода. Символы, вводимые с клавиатуры терминала, помещаются в "сырую" очередь ввода. Кроме того, если требуется эхо (вывод печатаемых символов на экран), копии этих символов добавляются в очередь вывода.
Если разрешен канонический режим обработки ввода (обычно это делается по умолчанию), символы из "сырой" очереди подвергаются предобработке при копировании в каноническую очередь ввода. Копирование происходит по строкам, когда поступает символ перевода строки (NL). Пользовательская программа читает строки ввода из канонической очереди.
Каноническая предобработка ввода включает обработку символов забоя и стирания строки. Символ забоя ERASE (на видеотерминалах это обычно '\0x8' (Ctrl-H, ASCII BS) или '\0x7F' (ASCII DEL); на телетайпах часто использовался символ #) удаляется вместе с символом, введенным перед ним.
Клавиша «Backspace» на терминале может быть настроена посылать либо ASCII BS, либо ASCII DEL. Клавиша «Del» в xterm или gnome-terminal посылает последовательность ASCII ESC [3~. У gnome-terminal поведение обоих клавиш настраивается на закладке настроек Edit->Profile Preferences->Compatibility.
Символ стирания строки KILL (Ctrl-W по умолчанию) приводит к стиранию всей текущей строки.
Например, предполагая, что символ забоя равен ASCII BS, вы набираете на клавиатуре:
datxBSe
Символы, набранные на клавиатуре, записываются в "сырую" очередь по мере ввода. Затем при копировании из "сырой" очереди в каноническую, символы просматриваются. При этом символы BS и стоящий перед ним выбрасываются. Поэтому, программа, читающая с терминала, получит строку:
date
При выводе, символы, генерируемые вашей прикладной программой, накапливаются в выходной очереди. При этом может происходить требуемая настройками постобработка.
Использование termios(3C)
Существует более пятидесяти различных параметров и флагов, управляющих терминальным интерфейсом. Эти параметры можно изменять через ioctl termio(7I), функции termios(3C) и команду stty(1). Ниже приводятся некоторые из основных характеристик терминала.
Параметры RS232
Используя флаг c_cflag, вы можете управлять скоростью передачи, количеством бит в символе, количеством стоповых битов, обработкой бита четности и т.д. Это необходимо потому, что протокол RS232 не имеет средств автосогласования указанных параметров, и их необходимо настраивать вручную так, чтобы настройки терминала и терминального порта компьютера совпадали. У псевдотерминалов эти параметры сохраняются только для совместимости; изменение большинства из них (кроме количества бит в символе) ни на что не влияют.
Отображение символов.
Вы можете управлять обработкой символов возврата каретки (CR) и перевода строки (NL). Вы можете преобразовывать NL в CR (INLCR) и CR в NL (ICRNL). Вы можете также игнорировать поступающие символы CR (IGNCR). Это полезно для терминалов, которые генерируют последовательность символов CR-NL при нажатии клавиши <RETURN>. На других терминалах, которые генерируют одиночный символ CR, лучше
принимать этот символ и преобразовывать его в NL. Флаги для этих режимов помещаются в c_iflag. Соответственно, флаги ONLCR и OCRNL в c_oflag используются для преобразования NL в CR-NL или CR в NL, соответственно, при выводе.
Для терминалов, которые отображают только буквы верхнего регистра, могут быть установлены флаги XCASE в c_iflag, IUCLC в c_iflag и OLCUC в c_oflag. Буквы верхнего регистра отображаются в нижний регистр при вводе и наоборот - при выводе. Буквы верхнего регистра предваряются символом обратной косой черты (backslash, \).
По умолчанию, некоторые терминалы используют семибитный код ASCII для представления символов. Однако может быть необходима работа с восьмибитными данными. Например, это может потребоваться программам, работающим с национальными алфавитами или UTF-8. Для того, чтобы выключить срезание восьмого бита при вводе, вы должны очистить флаг ISTRIP в
c_iflag, установить флаг CS8 для передачи восьмибитных символов и, возможно, выключить контроль четности очисткой PARENB в c_cflag.
Задержки и табуляции.
Для механических терминалов можно установить различные флаги в c_oflag, управляющие задержками при обработке перевода строки, возврата каретки, горизонтальной табуляции, сдвига каретки назад (backspace), вертикальной табуляции и перевода страницы. Горизонтальная табуляция может преобразовываться в соответствующее число пробелов установкой флага TAB3.
(Продолжение на следующей странице)
Управление потоком.
Вывод на терминал может быть приостановлен нажатием СТОП-символа, по умолчанию CTRL-S, и возобновлен нажатием СТАРТ-символа, по умолчанию CTRL-Q. Эта возможность разрешается установкой флага IXON в c_flag. Иначе, эти символы не имеют специального смысла. Кроме того, если установить флаг IXANY, то любой символ будет возобновлять вывод. Для управления потоком вывода используется функция tcflow(2). Кроме управления потоком вывода, установкой флага IXOFF в c_iflag можно управлять потоком ввода. При этом, если входная очередь приближается к заполнению, драйвер терминального устройства пошлет
СТОП-символ для приостановки ввода, и СТАРТ-символ - для его возобновления. Это может быть полезно, если прикладная программа получает данные из удаленной системы.
Более удобный способ управлять потоком данных при выводе на терминал — это утилита more(1) или её аналоги. Однако надо подчеркнуть, что при использовании more(1), программа осуществляет вывод не на терминал, а в программный канал, направленный на вход more(1); это может повлиять на поведение некоторых программ.
Управляющие символы
При вводе некоторые символы имеют специальное значение. Например, # или ASCII BS
является символом забоя, CTRL-W — символом стирания строки, CTRL-D — концом ввода и т.д. Эти символы хранятся в массиве c_cc[] и могут быть изменены. Например, при использовании дисплея, гораздо удобнее использовать в качестве символа забоя BS (сдвиг каретки назад), чем #
Эхо
Терминалы обычно работают с UNIX-системами в полнодуплексном режиме. Это означает, что данные передаются в обоих направлениях одновременно и что компьютер обеспечивает эхо (отображение на экране или на печати) получаемых символов. Эхо выключается очисткой флага ECHO в c_lflag. Кроме того, стертые нажатием клавиши забоя символы могут затираться установкой флага ECHOE. Если установить флаг ECHOK, то стирание строки символом KILL будет приводить к переводу строки на терминале.
Немедленный ввод
Обычно символы при вводе накапливаются, пока не соберется полная строка, завершенная NL. Только после этого удовлетворяется запрос read(2), даже если он требовал только один символ. Значение, возвращаемое вызовом read(2), равно количеству прочитанных в действительности символов. Во многих прикладных программах, таких как редакторы форм или полноэкранные текстовые редакторы, строки ввода не имеют смысла. В таких программах необходимо читать символы по мере их ввода. При очистке флага ICANON в c_lflag вводимые символы не группируются в строки, и read(2) читает их по мере поступления. Этот режим известен также как режим неканонического ввода. Вместо этого удовлетворение запроса read(2) определяется параметрами MIN (минимальное количество нажатых клавиш) и TIME (промежуток времени
между введенными символами). Если ICANON установлен, то режим ввода называется каноническим.
(Продолжение на следующей странице)
"Сырой" терминальный ввод/вывод
Терминальные порты могут использоваться для подключения не только терминалов, но и других устройств, например, модемов, мышей или различной контрольно-измерительной аппаратуры. При работе с такими устройствами, прикладные программы и драйверы терминальных устройств могут быть вынуждены передавать и принимать произвольные восьмибитные данные. Это могут быть сообщения мыши о передвижении и нажатии кнопок, данные протокола PPP или поступающие с измерительного устройства данные. Для разрешения этого необходимо установить восьмибитные данные, неканонический ввод, запретить все отображения символов и управление потоком, устранить специальные значения всех управляющих символов и выключить эхо. В конце раздела приводится пример использования "сырого" терминального ввода/вывода.