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. Ниже приведены номера, приписанные функциям, и подразумеваемые символы:

0VINTRDEL
1VQUITFS
2VERASE#
3VKILL@
4VEOF (VMIN)EOT
5VEOL (VTIME)NUL
6VEOL2
7VSWTCHSUB

Поле c_iflag описывает основные параметры терминального ввода:

IGNBRK0000001Игнорировать ошибки протокола.
BRKINT0000002При ошибках протокола генерировать сигнал прерывания.
IGNPAR0000004Игнорировать символы с ошибками четности.
PARMRK0000010Отмечать ошибки четности.
INPCK0000020Разрешить контроль четности.
ISTRIP0000040Отбрасывать старший бит.
INLCR0000100Преобразовывать перевод строки в возврат каретки.
IGNCR0000200Игнорировать возвраты каретки.
ICRNL0000400Преобразовывать возврат каретки в перевод строки.
IUCLC0001000Преобразовывать большие буквы в малые.
IXON0002000Разрешить старт/стопное управление выводом.
IXANY0004000Разрешить любому символу возобновлять вывод.
IXOFF0010000Разрешить старт/стопное управление вводом.

Если установлен бит 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 определяет системную обработку вывода:

OPOST0000001Постпроцессировать вывод.
OLCUC0000002Преобразовывать малые буквы в большие.
ONLCR0000004Преобразовывать перевод строки в пару (перевод строки, возврат каретки).
OCRNL0000010Преобразовывать возврат каретки в перевод строки.
ONOCR0000020Не выдавать возврат каретки в нулевой колонке.
ONLRET0000040Перевод строки выполняет функции возврата каретки.
OFILL0000100Использовать для задержки передачу символов-заполнителей.
OFDEL0000200Символом-заполнителем является DEL (по умолчанию - NUL).
NLDLY0000400Выбрать задержку для перевода строки:
NL00
NL10000400
CRDLY0003000Выбрать задержку для возврата каретки:
CR00
CR10001000
CR20002000
CR30003000
TABDLY0014000Выбрать задержку для горизонтальной табуляции:
TAB00
TAB10004000
TAB20010000
TAB30014000 Разворачивать табуляцию в пробелы.
BSDLY0020000Выбрать задержку для возврата на шаг:
BS00
BS10020000
VTDLY0040000Выбрать задержку для вертикальной табуляции:
VT00
VT10040000
FFDLY0100000Выбрать задержку для перехода к новой странице:
FF00
FF10100000

Если установлен бит 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 описывает аппаратные характеристики линии и терминала:

CBAUD0000017Скорость передачи:
B00Освобождение линии.
B50000000150 бод.
B75000000275 бод.
B1100000003110 бод.
B1340000004134 бода.
B1500000005150 бод.
B2000000006200 бод.
B3000000007300 бод.
B6000000010600 бод.
B120000000111200 бод.
B180000000121800 бод.
B240000000132400 бод.
B480000000144800 бод.
B960000000159600 бод.
B19200000001619200 бод.
EXTA0000016Внешний A.
B38400000001738400 бод.
EXTB0000017Внешний B.
CSIZE0000060Размер символа:
CS505 бит.
CS600000206 бит.
CS700000407 бит.
CS800000608 бит.
CSTOPB0000100Посылать два стоп-бита, иначе один.
CREAD0000200Разрешить прием символов.
PARENB0000400Контролировать четность.
PARODD0001000Проверка на нечетность, иначе на четность.
HUPCL0002000Освобождение линии при последнем закрытии.
CLOCAL0004000Локальная линия связи, иначе коммутируемая.
RCV1EN0010000
XMT1EN0020000
LOBLK0040000Блокировать вывод экземпляра shell'а.

Биты CBAUD определяют скорость передачи данных. Нулевая скорость передачи, B0, используется для прекращения связи и освобождения линии. При нулевой скорости не будет выставляться сигнал готовности терминала к обработке данных, что обычно ведет к разрыву связи. Для любого вида аппаратуры игнорируются не поддерживаемые ею изменения скорости.

Биты CZISE задают размер символа в битах как для передачи, так и для приема данных. В этом размере не учитывается бит четности, если он есть. Если установлен режим CSTOPB, то используется два стоп-бита, в противном случае один. Например, при скорости 110 бод требуется два стоп-бита.

Если установлен режим PARENB, то действует как контроль четности, так и добавление к каждому символу бита четности. Если при этом установлен бит PARODD, выполняется проверка на нечетность, в противном случае - на четность.

Если установлен бит CREAD, то разрешен прием данных, в противном случае символы приниматься не будут.

Если установлен бит HUPCL, то линия связи будет освобождена, когда последний процесс, открывавший ее, закроет линию или завершится. В результате сигнал готовности терминала к обработке данных пропадет.

Если установлен бит CLOCAL, то считается, что линия связи локальная, с прямым соединением без модемного управления. В противном случае предполагается модемное управление.

Если установлен бит LOBLK, то вывод экземпляров shell'а, не являющихся текущими, будет блокироваться. В противном случае вывод разных экземпляров будет мультиплексироваться.

После открытия терминального файла будут установлены следующие аппаратные характеристики: B300, CS8, CREAD, HUPCL.

Поле c_lflag структуры termio используется для детализации режима работы с терминальной линией. Базовый режим (0) обеспечивает следующие возможности:

ISIG0000001Разрешить сигналы.
ICANON0000002Канонический ввод (обработка забоя и уничтожения).
XCASE0000004Каноническое представление больших/малых букв.
ECHO0000010Разрешить эхо.
ECHOE0000020Отображать символ забоя как тройку: возврат на шаг, пробел, возврат на шаг.
ECHOK0000040Выдавать перевод строки после символа уничтожения.
ECHONL0000100Отображать перевод строки.
NOFLSH0000200Запретить сброс после прерывания или выхода.

Если установлен бит 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) в Справочнике программиста.