TERMIO(7)
НАЗВАНИЕ
termio - общий терминальный интерфейс
ОПИСАНИЕ
Все асинхронные порты связи используют один и тот же
общий интерфейс, вне зависимости от подключенной аппаратуры.
Обычно при открытии файла, соответствующего терминалу,
процесс ожидает установления соединения. На практике
пользовательские программы редко сами открывают такие
файлы; они открываются программой getty(1M) и становятся пользовательским стандартным вводом, выводом и протоколом. Самый первый из терминальных файлов, не ассоциированных с группой процессов, при открытии его лидером группы становится управляющим терминалом для данной
группы. Управляющий терминал играет особую роль при обработке сигналов выхода и прерывания, как это обсуждается ниже. Управляющий терминал наследуется процессом,
порожденным посредством системного вызова fork(2). Изменением своей группы [с помощью системного вызова
setpgrp(2)] процесс может разорвать эту связь.
Терминалы работают в полностью дуплексном (двустороннем) режиме. Символы можно вводить в любой момент времени, даже когда происходит вывод. Потеря символов происходит только в двух случаях: когда переполняется системный буфер вводимых символов (что случается довольно
редко) или когда пользователь накопил максимально допустимое число вводимых символов, а никакая программа
их не прочитала. В текущей версии этот предел равен 256
символам. Если предел ввода достигнут, буфер сбрасывается и все сохраненные символы теряются без всякого
уведомления.
Обычно терминальный ввод обрабатывается построчно.
Строка ограничивается символами перевода строки, конца
файла или конца строки. Это означает, что при попытке
чтения процесс приостанавливается до тех пор, пока не
будет введена вся строка. При чтении, независимо от
числа запрошенных символов, будет выдано не более одной
строки, однако не обязательно всю строку читать сразу:
можно запросить любое количество символов (даже один) и
информация не будет потеряна.
Во время ввода обычно выполняется обработка символов
забоя и уничтожения. По умолчанию символ # "забивает"
последний введенный символ (но не далее начала строки).
Символ @ уничтожает всю вводимую строку и, быть может,
выдает перевод строки. Оба этих управляющих символа
воздействуют только на входной буфер. Так, после ввода
табуляции, развернутой в несколько пробелов, удаление
последнего символа приведет к удалению табуляции в буфере, но на экране будет удален лишь последний из пробелов.
При вводе некоторые символы выполняют специальные функции. Ниже перечислены эти функции и соответствующие
подразумеваемые символы:
- INTR (символ DEL в кодировке ASCII)
- Генерирует сигнал прерывания (SIGINT), посылаемый
всем процессам, для которых данный терминал является управляющим. Обычно каждый такой процесс терминируется, но есть средства, позволяющие проигнорировать этот сигнал или обработать его по-своему
[см. signal(2)].
- QUIT (CTRL+\, или символ FS в кодировке ASCII)
- Генерирует сигнал выхода (SIGQUIT), при стандартной реакции на который процесс не только терминируется, но и в текущем каталоге создается файл с
образом памяти процесса [см. core(4)].
- SWTCH (CTRL+Z, или символ SUB в кодировке ASCII)
- Используется менеджером семейства shell'ов shl(1)
для переключения между экземплярами shell'а.
- ERASE (#)
- Забивает предыдущий символ, но не далее начала
строки, отделенного символами NL, EOF или EOL.
- KILL (@)
- Уничтожает всю строку, выделенную символами NL,
EOF или EOL.
- EOF (CTRL+D, или символ EOT в кодировке ASCII)
- Может быть использован для генерации признака конца файла при вводе с терминала. При получении этого символа все буферизованные символы, не ожидая
перевода строки, передаются процессу, а сам символ
EOF отбрасывается. Таким образом, если буферизованных символов нет, то есть EOF встретился в начале строки, в процесс будет передано 0 символов,
что и является стандартным обозначением конца файла.
- NL (символ LF в кодировке ASCII)
- Стандартный разделитель строк (перевод строки).
Его нельзя изменить или экранировать.
- EOL (символ NUL в кодировке ASCII)
- Дополнительный разделитель строк, аналогичный NL.
Обычно не используется.
- EOL2
- Еще один дополнительный разделитель строк.
- STOP (CTRL+S, или символ DC3 в кодировке ASCII)
- Обычно используется для временной приостановки вывода, когда нужно прочитать текст на экране терминала. Если вывод приостановлен, символы STOP игнорируются и не читаются.
- START (CTRL+Q, или символ DC1 в кодировке ASCII)
- Используется для возобновления вывода, приостановленного с помощью символа STOP. Если вывод не приостановлен, то символы START игнорируются и не читаются. Символы START и STOP нельзя изменить или
экранировать.
Для выполнения функций INTR, QUIT, SWTCH, ERASE, KILL,
EOF и EOL можно назначить символы, отличные от подразумеваемых [см. stty(1)]. Символы ERASE, KILL и EOF можно
экранировать, то есть лишить их специальных функций,
если поместить перед ними символ \.
Если пропала несущая, то всем процессам, для которых
данный терминал является управляющим, посылается сигнал
освобождения линии (SIGHUP). Если не предусмотрено обработки этого сигнала, то его возникновение вызовет
терминирование процесса. Если сигнал освобождения игнорируется, то все последующие операции чтения возвращают
признак конца файла. Таким образом процессы, читающие с
терминала и проверяющие конец файла, могут соответствующим образом завершиться в случае разрыва связи.
При выполнении записи одного или более символов они передаются терминалу только тогда, когда вывод символов,
записанных ранее, завершен. Эхоотображение вводимых
символов выполняется посредством их постановки, по мере
поступления, в очередь вывода. Если процесс порождает
символы быстрее, чем они могут быть выведены, его приостановят, когда размер очереди вывода превысит некоторый предел. При уменьшении очереди до некоторого порогового значения выполнение программы возобновляется.
С помощью системного вызова ioctl(2) над терминальными
файлами можно выполнять различные управляющие действия.
Как правило, при этом используется следующая структура,
описанная во включаемом файле <termio.h>:
#define NCC 8
struct termio {
unsigned short c_iflag; /* Режимы ввода */
unsigned short c_oflag; /* Режимы вывода */
unsigned short c_cflag; /* Управляющие режимы */
unsigned short c_lflag; /* Локальные режимы */
char c_line; /* Режим работы с линией */
unsigned char c_cc[NCC];/* Управляющие символы */
};
Соответствие управляющих функций и символов задается в
массиве c_cc. Ниже приведены номера, приписанные функциям, и подразумеваемые символы:
0 | VINTR | DEL |
1 | VQUIT | FS |
2 | VERASE | # |
3 | VKILL | @ |
4 | VEOF (VMIN) | EOT |
5 | VEOL (VTIME) | NUL |
6 | VEOL2 |
7 | VSWTCH | SUB |
Поле c_iflag описывает основные параметры терминального
ввода:
IGNBRK | 0000001 | Игнорировать ошибки протокола. |
BRKINT | 0000002 | При ошибках протокола генерировать сигнал прерывания. |
IGNPAR | 0000004 | Игнорировать символы с ошибками четности. |
PARMRK | 0000010 | Отмечать ошибки четности. |
INPCK | 0000020 | Разрешить контроль четности. |
ISTRIP | 0000040 | Отбрасывать старший бит. |
INLCR | 0000100 | Преобразовывать перевод строки в возврат каретки. |
IGNCR | 0000200 | Игнорировать возвраты каретки. |
ICRNL | 0000400 | Преобразовывать возврат каретки в перевод строки. |
IUCLC | 0001000 | Преобразовывать большие буквы в малые. |
IXON | 0002000 | Разрешить старт/стопное управление выводом. |
IXANY | 0004000 | Разрешить любому символу возобновлять вывод. |
IXOFF | 0010000 | Разрешить старт/стопное управление вводом. |
Если установлен бит IGNBRK, то символы с ошибками протокола и четности игнорируются (то есть не поступают в
очередь ввода). В противном случае, при установленном
бите BRKINT, получение блока данных, содержащего только
нули, (нажатие клавиши прерывания) приведет к генерации
сигнала прерывания и опустошению очередей ввода/вывода.
Если установлен бит PARMRK, то символы с ошибкой протокола или четности (если они не игнорируются) вводятся в
виде последовательности из трех байт: 0377, 0, x, где x
- это данные, полученные при возникновении ошибки. Чтобы избежать в этом случае двусмысленности (если бит
ISTRIP не установлен) символ 0377 вводится как пара
0377, 0377. Если бит PARMRK не установлен, то при возникновении ошибки (которая не игнорируется) вводится
символ NUL (0).
Если установлен бит INPCK, то действует контроль четности при вводе, в противном случае контроль выключен.
Это позволяет формировать четность вывода без ошибок
четности при вводе.
Если установлен бит ISTRIP, то у допустимых вводимых
символов сначала отбрасывается старший бит; в противном
случае обрабатываются все 8 бит.
Если установлен бит INLCR, то вводимые символы перевода
строки преобразуются в возврат каретки. Если установлен
бит IGNCR, то символы возврата каретки игнорируются (не
вводятся); в противном случае, если установлен бит
ICRNL, символы возврата каретки преобразуются в перевод
строки.
Если установлен бит IUCLC, то большие буквы преобразуются в соответствующие малые буквы.
Если установлен бит IXON, то разрешено старт/стопное
управление выводом. Полученный символ STOP приостановит
вывод, а символ START его возобновит. Все старт/стопные
символы игнорируются, то есть не вводятся. Если установлен бит IXANY, то любой введенный символ возобновит
приостановленный вывод.
Если установлен бит IXOFF, то система будет передавать
старт/стопные символы, когда очередь ввода почти пуста/
заполнена.
В начальном состоянии все биты поля c_iflag равны 0.
Поле c_oflag определяет системную обработку вывода:
OPOST | 0000001 | Постпроцессировать вывод. |
OLCUC | 0000002 | Преобразовывать малые буквы в большие. |
ONLCR | 0000004 | Преобразовывать перевод строки в пару (перевод строки, возврат каретки). |
OCRNL | 0000010 | Преобразовывать возврат каретки в перевод строки. |
ONOCR | 0000020 | Не выдавать возврат каретки в нулевой колонке. |
ONLRET | 0000040 | Перевод строки выполняет функции возврата каретки. |
OFILL | 0000100 | Использовать для задержки передачу символов-заполнителей. |
OFDEL | 0000200 | Символом-заполнителем является DEL (по умолчанию - NUL). |
NLDLY | 0000400 | Выбрать задержку для перевода строки: |
NL0 | 0 |
NL1 | 0000400 |
CRDLY | 0003000 | Выбрать задержку для возврата каретки: |
CR0 | 0 |
CR1 | 0001000 |
CR2 | 0002000 |
CR3 | 0003000 |
TABDLY | 0014000 | Выбрать задержку для горизонтальной табуляции: |
TAB0 | 0 |
TAB1 | 0004000 |
TAB2 | 0010000 |
TAB3 | 0014000 Разворачивать табуляцию в пробелы. |
BSDLY | 0020000 | Выбрать задержку для возврата на шаг: |
BS0 | 0 |
BS1 | 0020000 |
VTDLY | 0040000 | Выбрать задержку для вертикальной табуляции: |
VT0 | 0 |
VT1 | 0040000 |
FFDLY | 0100000 | Выбрать задержку для перехода к новой странице: |
FF0 | 0 |
FF1 | 0100000 |
Если установлен бит OPOST, то выводимые символы постпроцессируются, иначе они передаются на терминал без
обработки. Характер обработки определяется остальными
битами режима вывода.
Если установлен бит OLCUC, то малые буквы преобразуются
при выводе в большие. Данный режим обычно используется
вместе с IUCLC.
Если установлен бит ONLCR, то перевод строки преобразуется в пару символов (перевод строки, возврат каретки).
Если установлен бит OCRNL, то возврат каретки преобразуется в перевод строки. Если установлен бит ONOCR, то
в колонке 0 (первая позиция строки) возврат каретки не
выводится. Если установлен бит ONLRET, то предполагается, что перевод строки выполняет функции возврата каретки; номер колонки становится нулевым, используются
задержки, определенные для возврата каретки. В противном случае предполагается, что перевод строки служит
только для перехода к новой строке: номер колонки не
изменяется. Если передается сам символ возврата каретки, номер колонки становится нулевым.
Биты задержки определяют время, на которое прекращается
передача. Задержка позволяет выполнить механическое или
иное перемещение, вызванное посылкой на терминал некоторых символов. В любом случае 0 означает отсутствие
задержки. Если установлен бит OFILL, то вместо временной задержки будет использоваться передача символов-заполнителей. Подобный режим полезен для высокоскоростных
терминалов, когда нужна минимальная задержка. Если установлен бит OFDEL, то символом-заполнителем является
DEL, в противном случае NUL.
Длительность задержки для вертикальной табуляции или
перехода к новой странице составляет примерно 2 секунды.
Задержка для перевода строки равна примерно 0.1 секунды. Если установлен бит ONLRET, то вместо задержки для
перевода строки используется задержка для возврата каретки. Если установлен бит OFILL, будут передаваться
два символа-заполнителя.
Задержка типа 1 для возврата каретки зависит от текущей
колонки, для типа 2 длится примерно 0.1 секунды, для
типа 3 - 0.15 секунды. Если установлен бит OFILL, то
при задержке типа 1 передаются два символа-заполнителя,
при задержке типа 2 - четыре символа.
При горизонтальной табуляции задержка типа 1 зависит от
текущей колонки. Для типа 2 она длится около 0.1 секунды. Тип 3 специфицирует, что табуляции должны развертываться в пробелы. Если установлен бит OFILL, то для задержки любого типа передаются два символа-заполнителя.
Задержка для возврата на шаг длится около 0.05 секунды.
Если установлен бит OFILL, то будет передаваться один
символ-заполнитель.
Фактические задержки зависят от скорости линии связи и
загруженности системы.
В начальном состоянии все биты поля c_oflag равны 0.
Поле c_cflag описывает аппаратные характеристики линии
и терминала:
CBAUD | 0000017 | Скорость передачи: |
B0 | 0 | Освобождение линии. |
B50 | 0000001 | 50 бод. |
B75 | 0000002 | 75 бод. |
B110 | 0000003 | 110 бод. |
B134 | 0000004 | 134 бода. |
B150 | 0000005 | 150 бод. |
B200 | 0000006 | 200 бод. |
B300 | 0000007 | 300 бод. |
B600 | 0000010 | 600 бод. |
B1200 | 0000011 | 1200 бод. |
B1800 | 0000012 | 1800 бод. |
B2400 | 0000013 | 2400 бод. |
B4800 | 0000014 | 4800 бод. |
B9600 | 0000015 | 9600 бод. |
B19200 | 0000016 | 19200 бод. |
EXTA | 0000016 | Внешний A. |
B38400 | 0000017 | 38400 бод. |
EXTB | 0000017 | Внешний B. |
CSIZE | 0000060 | Размер символа: |
CS5 | 0 | 5 бит. |
CS6 | 0000020 | 6 бит. |
CS7 | 0000040 | 7 бит. |
CS8 | 0000060 | 8 бит. |
CSTOPB | 0000100 | Посылать два стоп-бита, иначе один. |
CREAD | 0000200 | Разрешить прием символов. |
PARENB | 0000400 | Контролировать четность. |
PARODD | 0001000 | Проверка на нечетность, иначе на четность. |
HUPCL | 0002000 | Освобождение линии при последнем закрытии. |
CLOCAL | 0004000 | Локальная линия связи, иначе коммутируемая. |
RCV1EN | 0010000 |
XMT1EN | 0020000 |
LOBLK | 0040000 | Блокировать вывод экземпляра shell'а. |
Биты CBAUD определяют скорость передачи данных. Нулевая
скорость передачи, B0, используется для прекращения
связи и освобождения линии. При нулевой скорости не будет выставляться сигнал готовности терминала к обработке данных, что обычно ведет к разрыву связи. Для любого
вида аппаратуры игнорируются не поддерживаемые ею изменения скорости.
Биты CZISE задают размер символа в битах как для передачи, так и для приема данных. В этом размере не учитывается бит четности, если он есть. Если установлен режим CSTOPB, то используется два стоп-бита, в противном
случае один. Например, при скорости 110 бод требуется
два стоп-бита.
Если установлен режим PARENB, то действует как контроль
четности, так и добавление к каждому символу бита четности. Если при этом установлен бит PARODD, выполняется
проверка на нечетность, в противном случае - на четность.
Если установлен бит CREAD, то разрешен прием данных, в
противном случае символы приниматься не будут.
Если установлен бит HUPCL, то линия связи будет освобождена, когда последний процесс, открывавший ее, закроет линию или завершится. В результате сигнал готовности терминала к обработке данных пропадет.
Если установлен бит CLOCAL, то считается, что линия
связи локальная, с прямым соединением без модемного управления. В противном случае предполагается модемное
управление.
Если установлен бит LOBLK, то вывод экземпляров
shell'а, не являющихся текущими, будет блокироваться. В
противном случае вывод разных экземпляров будет мультиплексироваться.
После открытия терминального файла будут установлены
следующие аппаратные характеристики: B300, CS8, CREAD,
HUPCL.
Поле c_lflag структуры termio используется для детализации режима работы с терминальной линией. Базовый режим (0) обеспечивает следующие возможности:
ISIG | 0000001 | Разрешить сигналы. |
ICANON | 0000002 | Канонический ввод (обработка забоя и
уничтожения). |
XCASE | 0000004 | Каноническое представление больших/малых букв. |
ECHO | 0000010 | Разрешить эхо. |
ECHOE | 0000020 | Отображать символ забоя как тройку:
возврат на шаг, пробел, возврат на шаг. |
ECHOK | 0000040 | Выдавать перевод строки после символа
уничтожения. |
ECHONL | 0000100 | Отображать перевод строки. |
NOFLSH | 0000200 | Запретить сброс после прерывания или
выхода. |
Если установлен бит ISIG, то каждый вводимый символ
сравнивается со специальными управляющими символами
INTR, SWTCH и QUIT. В случае совпадения выполняется соответствующая функция. Если бит ISIG не установлен, то
никакой проверки не производится. Таким образом, выполнение упомянутых специальных функций ввода возможно
только при установленном бите ISIG. Эти функции могут
быть отключены по отдельности, с помощью смены управляющего символа на маловероятное или невозможное значение (например, 0377).
Если установлен бит ICANON, то разрешена каноническая
обработка ввода. Это означает разрешение функций редактирования [забоя (ERASE) и уничтожения (KILL)], об единения вводимых символов в строки, разделенные символами
NL, EOF и EOL. Если бит ICANON не установлен, то запросы на чтение удовлетворяются прямо из очереди ввода.
Запрос на чтение не будет удовлетворен до тех пор, пока
не поступит по крайней мере MIN символов или не истечет
время задержки TIME между поступлениями символов (то
есть время TIME начинает отсчитываться после поступления первого символа). Такой подход позволяет эффективно
читать во время вспышек активности ввода и в то же время разрешает посимвольный ввод. Нулевое значение TIME
трактуется как бесконечная задержка, то есть запрос на
чтение будет удовлетворен, только когда поступит по
крайней мере MIN символов. Значения MIN и TIME хранятся
соответственно в позициях для символов EOF и EOL (см.
включаемый файл <sys/termio.h>). Время задается в десятых долях секунды.
Если установлены биты XCASE и ICANON, то при вводе буква воспринимается как большая, когда перед ней стоит
символ \, и выводится в виде пары символов, первый из
которых есть \. В этом режиме следующие управляющие
последовательности генерируются при выводе и воспринимаются при вводе:
для ввода символа: | используйте: |
` | \' |
| | \! |
~ | \^ |
{ | \( |
} | \) |
\ | \\ |
Например, A вводится как \a, \n как \\n, а \N как \\\n.
Если установлен бит ECHO, то при получении символа происходит его эхоотображение.
Когда установлен бит ICANON, возможны следующие функции
эхоотображения. Если установлены биты ECHO и ECHOE, то
символ забоя отображается как тройка ASCII-символов
(BS, SP, BS), в результате чего последний из введенных
перед этим символов исчезнет с экрана. Если установлен
бит ECHOE, а ECHO нет, то символ забоя отображается как
пара (SP BS). Если установлен бит ECHOK, то после символа уничтожения будет выведен перевод строки (NL),
чтобы подчеркнуть факт уничтожения. Заметим, что символы забоя и уничтожения могут быть экранированы, если
перед ними поместить \, и тогда они теряют специальный
смысл. Если установлен бит ECHONL, то перевод строки
будет отображаться даже в том случае, когда не установлен бит ECHO, что полезно для терминалов с локальным
эхоотображением (так называемых полудуплексных). Символ
конца файла (EOF) не отображается, если только он не
экранирован. Так как подразумеваемым признаком конца
файла служит ASCII-символ EOT (конец передачи), эхоотображение конца файла привело бы к освобождению линии
терминалами, отвечающими на EOT.
Если установлен бит NOFLSH, то не будет выполняться
обычно применяемый сброс очередей ввода и вывода при
получении символов выхода, переключения и прерывания.
В начальном состоянии все биты поля c_lflag равны 0.
Основные системные вызовы ioctl(2) для терминальных
файлов имеют вид:
ioctl (fildes, command, arg)
struct termio *arg;
Подобный вид имеют следующие команды:
- TCGETA
- Получить параметры, ассоциированные с данным терминалом и поместить их в структуру типа termio, на
которую указывает аргумент arg.
- TCSETA
- Присвоить параметрам, ассоциированным с данным
терминалом, значения из структуры, на которую указывает аргумент arg.
- TCSETAW
- Дождаться окончания вывода, прежде чем устанавливать новые параметры. Эту форму следует применять
при изменении параметров, влияющих на вывод.
- TCSETAF
- Дождаться окончания вывода, затем сбросить очередь
ввода и установить новые параметры.
Дополнительные вызовы
ioctl(2) имеют вид:
ioctl (fildes, command, arg)
int arg;
Этот вид имеют следующие команды:
- TCSBRK
- Подождать окончания вывода; затем, если arg равен
нулю, вызвать нарушение протокола (в течение 0.25
секунды посылать нулевые биты).
- TCXONC
- Старт/стопное управление. Если arg равен нулю, то
приостановить вывод; если 1, то возобновить приостановленный вывод.
- TCFLSH
- Если arg равен 0, то сбросить очередь ввода; если
1, то сбросить очередь вывода; если 2, то сбросить
обе очереди.
ФАЙЛЫ
/dev/tty*
<sys/termio.h>
СМ. ТАКЖЕ
stty(1) в Справочнике пользователя.
fork(2), ioctl(2), setpgrp(2), signal(2) в Справочнике
программиста.