Вход/Регистрация
Разработка приложений в среде Linux. Второе издание
вернуться

Троан Эрик В.

Шрифт:

16.5.7. Управляющие символы

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

VMIN
и
VTIME
) в массиве
с_сс
обозначает действие и содержит код символа, предназначенный для этого действия. Например, установите символ прерывания на Control-C с помощью следующего кода:

ts.с_сс[VINTR] = CTRLCHAR('С');

Макрос

CTRLCHAR
определен как

#define CTRLCHAR(ch) ((ch)&0x1F)

Некоторые системы имеют макрос

CTRL
, определенный в
<termios.h>
, но не поддерживаемый во всех системах, поэтому определение нашей собственной версии будет более надежным. Мы используем запись ^C для обозначения Control-C.

Расположения символов, не определенные POSIX, активны только в случае установки локального управляющего флага

IEXTEN(c_lflag)
.

Управляющие символы, которые вы видите как индексы массива

с_сс
, перечислены ниже.

VINTR
Смещение
VINTR
обычно устанавливается в
^C
. Оно обычно сбрасывает на диск очереди ввода-вывода и передает
SIGINT
элементам группы процесса переднего плана, ассоциированным с tty. Процессы, неявно обрабатывающие
SIGINT
, немедленно завершаются.
VQUIT
Смещение
VQUIT
обычно устанавливается в
^\
. Оно обычно сбрасывает на диск очереди ввода-вывода и передает
SIGQUIT
элементам группы процесса переднего плана, ассоциированным с tty. Процессы, неявно обрабатывающие
SIGQUIT
, завершаются, при возможности сброса дампа ядра (см. главу 10).
VERASE
Смещение
VERASE
обычно устанавливается в
^H
или
^?
. В каноническом режиме оно обычно стирает предыдущий символ в строке. В неформатируемом режиме это несущественно.
VKILL
Смещение
VKILL
обычно установлено в
^U
. В каноническом режиме оно обычно стирает всю строку. В неформатируемом режиме это несущественно.
VEOF
Смещение
VEOF
обычно установлено в
^D
. В каноническом режиме оно заставляет
read
на файловом дескрипторе возвращать 0, сигнализируя о состоянии конца файла. На некоторых системах оно может делить пространство с символом
VMIN
, активным лишь в неформатируемом режиме. (Это не проблема, если вы сохраните
struct termios
с каноническими установками режима для восстановления действий в неформатируемом режиме, что все равно присуще практике программирования с применением
termios
.)
VSTOP
Смещение
VSTOP
обычно установлено в
^S
. Оно заставляет tty приостановить передачу выходных данных до получения символа
VSTART
, или, в случае установки
IXANY
, до получения любого символа.
VSTART
Смещение
VSTART
обычно установлено в
^Q
. Оно запускает приостановленный вывод tty.
VSUSP
Смещение
VSUSP
обычно установлено в
^Z
. Оно вызывает передачу
SIGTSTP
текущей группе процессов переднего плана; более подробно об этом рассказывается в главе 15.
VEOL
и
VEOL2
В каноническом режиме эти символы, а также символ новой строки (
'\n'
), сигнализируют о состоянии конца строки. Это вызывает передачу скомпонованного буфера и запуск нового буфера. На некоторых системах
VEOL
может делить пространство с символом
VTIME
, активным лишь в неформатируемом режиме, так же, как
VEOF
может делить пространство с
VMIN
. Символ
VEOL2
в POSIX не определен.
VREPRINT
Смещение
VREPRINT
обычно установлено в
^R
. В каноническом режиме в случае установки флага
ECHO
оно вызывает локальное отражение символа
VREPRINT
, новой строки (и возврата каретки, если это допустимо), а также перепечатку всего текущего буфера. Этот символ в POSIX не определен.
VWERASE
Смещение
WERASE
обычно установлено в
^W
. В каноническом режиме оно стирает все пробелы в конце буфера, затем все остальные символы, что дает эффект стирания предыдущего слова в строке. Этот символ в POSIX не определен.
VLNEXT
Смещение
VLNEXT
обычно установлено в
^V
. Само оно не вводится в буфер, но вызывает литеральное помещение в буфер следующего символа, даже если это один из управляющих символов. Для того чтобы ввести один литеральный символ
VLNEXT
, введите его дважды. Этот символ в POSIX не определен.

Для отключения любой позиции управляющего символа установите его значение в

_POSIX_VDISABLE
. Это работает только в случае определения
_POSIX_VDISABLE
как значения, не равного -1.
_POSIX_VDISABLE
работает в Linux, но переносимая программа, к сожалению, не сможет зависеть от отключения расположений управляющих символов во всех системах.

16.5.8. Локальные флаги

Флаги локального режима влияют на локальную обработку, что в какой-то мере относится к способу сбора символов перед их выводом. Когда устройство находится в каноническом режиме (режиме с обработкой), символы отражаются локально без передачи в удаленную систему до тех пор, пока не встретится символ новой строки. На этом этапе передается вся строка, а удаленный конец обрабатывает ее без повторного отражения. В неформатируемом режиме каждый символ передается в удаленную систему в таком виде, в каком он принимается. Иногда символ отображается только удаленной системой, иногда только локальной, а иногда, например, при чтении пароля, он и вовсе не отображается.

Некоторые флаги могут вести себя иначе, в зависимости от того, в каком режиме находится терминал: каноническом или неформатируемом. Флаги, ведущие себя иначе в каноническом и неформатируемом режимах, отмечены.

Флаги, работающие на

c_cflag
, перечислены ниже.

ICANON
При установке
ICANON
включается канонический режим. Если
ICANON
не установлен, включается неформатируемый режим.
ECHO
При установке
ECHO
включается локальное эхо. Если
ECHO
не установлен, все остальные флаги, названия которых начинаются с
ECHO
, эффективно отключаются и функционируют так, как будто они все, кроме
ECHONL
, не установлены.
ECHOCTL
При установке
ECHOCTL
управляющие символы выводятся как
^C
, где
С
— это символ, формирующийся добавлением восьмеричного 0100 к управляющему символу, по модулю восьмеричного 0200. Поэтому Control-C отображается как
^C
, a Control-? (восьмеричный 0177) отображается как
^?
(
?
— это восьмеричный 77). Этот флаг в POSIX не определен.
ECHOE
В каноническом режиме при установке
ECHOE
в случае получения символа
ERASE
предыдущий символ на дисплее по возможности стирается.
ECHOK
и
ECHOKE
В каноническом режиме при получении символа
KILL
вся текущая строка стирается из буфера. Если не установлены ни
ECHOK
, ни
ECHOKE
, ни
ECHOE
, выводится представление символа
KILL
с помощью
ECHOCTL
(
^U
по умолчанию) для обозначения стертой строки. Если установлены
ECHOE
и
ECHOK
, но
ECHOKE
не установлен, выводится представление символа
KILL
с помощью
ECHOCTL
, сопровождаемое новой строкой, которая затем обрабатывается
OPOST
в случае установки
OPOST
. Если установлены
ECHOE
,
ECHOK
и
ECHOKE
, строка стирается. См. описание
ECHOPRT
для другой вариации на эту тему. Флаг
ECHOKE
в POSIX не определен. В системах без флага
ECHOKE
установка флага
ECHOK
может быть эквивалентна установке и
ECHOK
, и
ECHOKE
в Linux.
ECHONL
В каноническом режиме при установке
ECHONL
символы новой строки (
'\n'
) отражаются даже в том случае, если
ECHO
не установлен.
ECHOPRT
В каноническом режиме при установке
ECHOPRT
символы выводятся при стирании, когда принимаются символы
ERASE
или
WERASE
(или
KILL
, если установлены
ECHOK
и
ECHOKE
). Когда принимается первый в последовательности символ стирания, выводится
\
, а при выводе последнего символа стирания (достигается конец строки или вводится нестертый символ), выводится
/
. Каждый вводимый вами нормальный символ просто отображается. Поэтому ввод
asdf
, сопровождаемый двумя символами
ERASE
, а также
df
и символом
KILL
, будет выглядеть следующим образом:
asdf\fd/df\fdsa/
. Этот флаг полезен для отладки и использования документирующих терминалов вроде первоначального телетайпа, где символы печатаются на бумаге; в другом случае он не пригодится. Этот флаг в POSIX не определен.
ISIG
Если установлен
ISIG
, управляющие символы
INTR
,
QUIT
и
SUSP
вызывают отправку соответствующего сигнала (
SIGINT
,
SIGQUIT
или
SIGTSTP
соответственно; см. главу 12) всем процессам в текущей группе процессов переднего плана на данном tty.
NOFLSH
Обычно при получении символов
INTR
и
QUIT
очереди ввода и вывода сбрасываются. При установке
NOFLSH
очереди не сбрасываются.
TOSTOP
Если установлен
TOSTOP
, то в том случае, когда процесс, не находящийся в текущей группе процессов переднего плана, пытается выполнить запись в свой управляющий терминал, передается
SIGTTOU
всей группе процессов, членом которой является данный процесс. По умолчанию этот сигнал останавливает процесс, как при нажатии комбинации клавиш, соответствующей символу
SUSP
.
IEXTEN
Этот флаг описан в POSIX как определяемый реализацией. Он включает обработку символов ввода, определяемую реализацией. Хотя переносимые программы не устанавливают этот бит,
IUCLC
и определенные возможности стирания символов в Linux зависимы от его установки. К счастью, он чаще всего разрешен по умолчанию в системах Linux, поскольку ядро изначально разрешает его при установке tty, поэтому обычно не нужно устанавливать его по какой-либо причине.

16.5.9. Управление

read

Два элемента в массиве

с_сс
не являются управляющими символами и имеют отношение только к неформатируемому режиму:
VTIME
и
VMIN
. В этом режиме они определяют, когда возвращается
read
. В каноническом режиме
read
возвращается только в том случае, если строки были собраны или был достигнут конец файла, за исключением случая установки опции
O_NONBLOCK
.

В неформатируемом режиме считывание по одному байту за раз неэффективно. Также неэффективно опрашивать порт чтением в неблокируемом режиме. Существуют два намного более эффективных дополнительных метода чтения.

Первый заключается в использовании

poll
, как описано в главе 13 и демонстрируется в коде
robin.с
. Если
poll
сообщает, что файловый дескриптор готов к чтению, то известно, что вы можете немедленно прочитать некоторое количество байтов. Однако сочетание
poll
со вторым методом сделает ваш код более эффективным, предоставляя возможность считывать больше байтов за один раз.

"Управляющие символы"

VTIME
и
VMIN
состоят в сложных взаимоотношениях.
VTIME
определяет промежуток времени для ожидания в десятых долях секунды (он не может быть больше
cc_t
, обычно это 8-битный
unsigned char
), который также может равняться нулю.
VMIN
определяет минимальное количество байт для ожидания (не для считывания — третий аргумент
read
определяет максимальное количество байтов для считывания), которое тоже может равняться нулю.

• Если

VTIME
равен нулю,
VMIN
определяет количество байт для ожидания. Вызов
read
не возвращается, пока не будут считано
VMIN
байт или пока не будет получен сигнал.

• Если

VMIN
равен нулю,
VTIME
определяет количество десятых частей секунд для ожидания
read
перед возвращением, даже если данные недоступны. В таком случае
read
, возвращающий нуль, необязательно сигнализирует о состоянии конца файла, как он обычно делает.

  • Читать дальше
  • 1
  • ...
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: