Программирование в стандарте POSIX

       

Основные понятия и объекты


В стандарте POSIX-2001 терминал или терминальное устройство определяется как символьный специальный файл, удовлетворяющий спецификациям общего терминального интерфейса.

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

Обычно терминальное устройство работает в полнодуплексном режиме, когда ввод и вывод могут совмещаться во времени.

С каждым терминальным устройством ассоциирована очередь ввода, куда система помещает входные данные до того, как их прочитают прикладные процессы. На размер этой очереди (в байтах) может быть наложено ограничение {MAX_INPUT}. Поддерживается также очередь вывода, где хранятся записанные прикладными процессами, но еще не выведенные на терминал символы.

Ввод может происходить в каноническом и неканоническом режимах.   Канонический режим означает построчную буферизацию ввода системой, т. е. запрос на чтение из прикладной программы будет удовлетворен лишь после того, как с клавиатуры поступит символ перевода строки или конца файла, а прочитает программа заведомо не больше одной строки, независимо от того, сколько байт она запросила. На размер строки может быть наложено ограничение {MAX_CANON}. Канонический режим подразумевает также естественную обработку системой символов забоя и уничтожения строки.

(Отметим, что в каноническом режиме приложение не обязано сразу прочитать всю буферизованную строку. Можно запросить любое количество байт (даже один), и данные не будут потеряны.)

В неканоническом режиме входные данные не подвергаются препроцессированию системой, а обработка запроса на чтение зависит от двух параметров - MIN и TIME. Запрос на чтение не будет удовлетворен, пока не поступит по крайней мере MIN байт или не истечет время задержки TIME (время задается в десятых долях секунды).
Нулевое значение TIME трактуется как бесконечная задержка.

Более точно, если MIN > 0, TIME трактуется как задержка между поступлениями байт; следовательно, отсчет времени начинается после прихода очередного байта. Если MIN = 0, TIME означает общее время обслуживания запроса на чтение. Такой подход позволяет эффективно читать во время вспышек активности ввода и не препятствует побайтному вводу.

Помимо режима, канонического или нет, на передачу данных читающему процессу оказывает влияние флаг O_NONBLOCK, устанавливаемый функциями open() или fcntl(), а на обработку входных символов - режимы ввода и локальные режимы. Подобная обработка может включать, например, эхоотображение вводимых символов.

Подвергаются обработке системой (в соответствии с режимами вывода) и выводимые прикладной программой символы (в частности, они могут буферизоваться).

Ряд управляющих символов играет специальную роль при вводе и/или выводе. Кратко опишем эти функции, не уточняя их соответствия с нажатиями на клавиатуре, поскольку оно зависит от реализации. Отметим, что за некоторыми очевидными исключениями (например, перевод строки), специальные управляющие символы не передаются читающему процессу.

INTR



Генерирует сигнал прерывания (SIGINT), посылаемый всем процессам, для которых данный терминал является управляющим.

QUIT

Генерирует сигнал выхода.

ERASE

При каноническом режиме ввода устраняет предыдущий символ, но не далее начала строки.

KILL

При каноническом режиме ввода уничтожает всю строку.

EOF

При каноническом режиме ввода при получении этого символа все буферизованные байты передаются процессу, а сам символ EOF отбрасывается. Таким образом, если буферизованных байт нет, т. е. EOF встретился в начале строки, в процесс будет передано нуль байт, что и является стандартным обозначением конца файла.

NL

Стандартный разделитель строк (перевод строки) при каноническом режиме ввода. Его нельзя изменить.

EOL

Дополнительный разделитель строк, аналогичный NL, при каноническом режиме ввода.Обычно не используется.

SUSP

Генерирует сигнал остановки.

STOP

Специальный символ как при вводе, так и при выводе, распознаваемый в случае наличия флагов IXON (управление выводом) или IXOFF (управление вводом). Обычно используется для временной приостановки вывода, когда нужно прочитать текст на экране терминала.

START

Употребляется для возобновления вывода, приостановленного с помощью символа STOP.

CR

При каноническом режиме ввода и выполнении некоторых дополнительных условий - эквивалент перевода строки.



Обычно не используется.

SUSP

Генерирует сигнал остановки.

STOP

Специальный символ как при вводе, так и при выводе, распознаваемый в случае наличия флагов IXON (управление выводом) или IXOFF (управление вводом). Обычно используется для временной приостановки вывода, когда нужно прочитать текст на экране терминала.

START

Употребляется для возобновления вывода, приостановленного с помощью символа STOP.

CR

При каноническом режиме ввода и выполнении некоторых дополнительных условий - эквивалент перевода строки.

Центральную роль в управлении терминалами играет структура termios, определенная во включаемом файле <termios.h>. Она должна содержать по крайней мере следующие поля.

tcflag_t c_iflag; /* Режимы ввода */ tcflag_t c_oflag; /* Режимы вывода */ tcflag_t c_cflag; /* Управляющие режимы */ tcflag_t c_lflag; /* Локальные режимы */ cc_t c_cc [NCCS]; /* Специальные управ- ляющие символы */

Типы tcflag_t, cc_t и фигурирующий далее speed_t должны определяться реализацией посредством typedef как беззнаковые целые.

Обращение к элементам массива c_cc, хранящего специальные управляющие символы, которые могут быть изменены, выполняется с помощью индексов с именами, полученными вставкой буквы V перед названием символа: VEOF, VEOL, VERASE, VINTR, VKILL, VQUIT, VSTART, VSTOP, VSUSP. Кроме того, еще два индекса, VMIN и VTIME, используются для работы со значениями MIN и TIME и могут совпадать с VEOF и VEOL, соответственно (поскольку символы EOF и EOL нужны только в каноническом режиме, а значения MIN и TIME - только в неканоническом).

Поле c_iflag структуры termios описывает основные параметры терминального ввода.

BRKINT

При разрыве соединения (когда в течение времени, превышающего длительность передачи байта, поступают нулевые биты) генерировать сигнал прерывания и сбрасывать очереди ввода/вывода.

ICRNL

Преобразовывать возврат каретки в перевод строки.

IGNBRK

Игнорировать разрыв соединения.

IGNCR

Игнорировать возврат каретки.

IGNPAR

Игнорировать символы с ошибками четности.



INLCR

Преобразовывать перевод строки в возврат каретки.

INPCK

Разрешить контроль четности.

ISTRIP

Отбрасывать старший бит, обрезая байты до семи бит.

IXOFF

Разрешить старт/стопное управление вводом.

IXON

Разрешить старт/стопное управление выводом.

PARMRK

Отмечать ошибки четности.

Поле c_oflag определяет системную обработку вывода. К числу обязательных для поддержки стандарт POSIX-2001 относит только один флаг - OPOST> (постпроцессировать вывод). В расширение XSI входят флаги, определяющие характер постпроцессирования: ONLCR (преобразовывать перевод строки в пару - перевод строки, возврат каретки), OCRNL (преобразовывать возврат каретки в перевод строки), NLDLY (выбрать задержку для перевода строки) и т.п.

Поле управляющих режимов c_cflag описывает аппаратные характеристики линии и терминала: размер символа в битах (CSIZE: от CS5 - 5 бит до CS8 - 8 бит), число стоп-бит (CSTOPB: два стоп-бита), освобождение линии при закрытии последнего файлового дескриптора, ассоциированного с терминалом (HUPCL), контроль четности (PARENB: контроль включен; PARODD: проверка на нечетность) и т.п.

Стандарт осторожен в части представления скорости передачи. Оговаривается только, что скорость хранится в структуре termios как значение типа speed_t, но не утверждается, что она представлена как часть поля c_cflag (хотя в исторически сложившихся реализациях это так). Допустимые значения скорости задаются именованными константами: от B0 - нулевой, означающей разрыв соединения, до B38400 - 38400 бит/сек.

Поле локальных режимов c_lflag структуры termios используется для управления различными характеристиками терминала. В их число входят:

ECHO

Включить эхоотображение.

ECHOE

Отображать символ забоя как тройку (возврат на шаг, пробел, возврат на шаг).

ECHOK

Отображать символ уничтожения строки (по крайней мере путем выдачи перевода строки).

ECHONL

Включить эхоотображение перевода строки.

ICANON

Канонический режим ввода.

ISIG

Разрешить сигналы. Если установлен флаг ISIG, то каждый вводимый символ сравнивается со специальными управляющими символами INTR, QUIT и SUSP.В случае совпадения выполняется ассоциированная функция.


Содержание раздела