Системное программирование в UNIX средствами Free Pascal

Параметры MIN и TIME


Параметры MIN и TIME имеют значение только при выключенном флаге ICANON. Они предназначены для тонкой настройки управления вводом данных. Параметр MIN задает минимальное число символов, которое должен получить драйвер терминала для возврата из вызова fdread. Параметр TIME задает значение максимального интервала ожидания; этот параметр обеспечивает еще один уровень управления вводом с терминала. Время ожидания измеряется десятыми долями секунды.

Значения параметров MIN и МАХ находятся в массиве с_сс структуры termios, описывающей состояние терминала. Их индексы в массиве определяются постоянными VMIN и VTIME из файла stdio. Следующий фрагмент программы показывает, как можно задать их значения:

uses stdio, linux;

var

  tdes:termios;

  ttyfd:longint;

(* Получает текущее состояние *)

tcgetattr(ttyfd, tdes);

tdes.c_lflag := tdes.c_lflag and (not ICANON); (* Отключает канонический режим *)

tdes.c_cc[VMIN] := 64;   (* В символах *)

tdes.c_cc[VTIME] := 2;   (* В десятых долях секунды *)

tcsetattr(0, TCSAFLUSH, &tdes);

Константы VMIN и VTIME обычно имеют те же самые значения, что и постоянные VEOF и VEOL. Это означает, что параметры MIN и TIME занимают то же положение, что и символы eof и еоl. Следовательно, при переключении из канонического в неканонический режим нужно обязательно задавать значения параметров MIN и TIME, иначе может наблюдаться странное поведение терминала. (В частности, если символу eof

соответствует комбинация клавиш Ctrl+D,

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

Существуют четыре возможных комбинации параметров MIN и TIME:

–        оба параметра MIN и TIME равны нулю. При этом возврат из вызова fdread обычно происходит немедленно. Если в очереди ввода терминала присутствуют символы (напомним, что попытка ввода может быть осуществлена в любой момент времени), то они будут помещены в буфер процесса. Поэтому, если программа переводит свой управляющий терминал в режим прямого доступа при помощи сброса флага ICANON и оба параметра MIN и TIME равны нулю, то вызов




nread := fdread(0, buffer, SOMESZ);

вернет произвольное число символов от нуля до SOMESZ в зависимости от того, сколько символов находится в очереди в момент выполнения вызова;

–        параметр MIN больше нуля, а параметр TIME равен нулю. В этом случае таймер не используется. Вызов fdread завершится только после того, как будут считаны MIN символов. Это происходит даже в том случае, если вызов read запрашивал меньше, чем MIN символов.

В самом простом варианте параметр MIN равен единице, а параметр TIME – нулю, что приводит к возврату из вызова fdread после получения каждого символа из линии терминала. Это может быть полезно при чтении с клавиатуры терминала, хотя могут возникнуть проблемы с клавишами, посылающими последовательности из нескольких символов;

–        параметр MIN равен нулю, а параметр TIME больше нуля. В этом случае параметр MIN не используется. Таймер запускается сразу же после выполнения вызова fdread. Возврат из вызова read происходит, как только вводится первый символ. Если заданный интервал времени истекает (то есть проход время, заданное в параметре TIME в десятых долях секунды), то вызов read возвращает нулевые символы;

–        оба параметра MIN и TIME больше нуля. Это, возможно, наиболее полезный и гибкий вариант. Таймер запускается после получения первого символа, а не при входе в вызов fdread. Если MIN символов будут получены до истечения заданного интервала времени, то происходит возврат из вызова fdread. Если таймер срабатывает раньше, то в программу пользователя возвращаются только символы, находящиеся при этом в очереди ввода. Этот режим работы полезен при поступлении ввода пакетами, которые посылаются в течение коротких интервалов времени. При этом упрощается программирование и уменьшается число необходимых системных вызовов. Такой режим также полезен, например, при работе с функциональными клавишами, которые посылают при нажатии на них сразу несколько символов.


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