Скачиваний:
56
Добавлен:
08.01.2014
Размер:
2.6 Mб
Скачать

9.3.3. Системный вызов fdwrite

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

9.3.4. Функции ttynameи isatty

Теперь представим две полезных функции, которые будем использовать в следующих примерах. Функция ttyname возвращает имя терминального устройства, связанного с дескриптором открытого файла, а функция isatty возвращает значение true (то есть истинно в терминах языка Паскаль), если дескриптор файла описывает терминальное устройство, и false (ложно) – в противном случае.

Описание

uses linux;

Function TTYName(var f):String;

Function IsATTY(var f):Boolean;

В обоих случаях параметр f является дескриптором открытого файла либо файловой переменной. Если f не соответствует терминалу, то функция ttyname вернет пустую строку.

Следующий пример – процедура what_tty выводит имя терминала, связанного с дескриптором файла, если это возможно:

(* Процедура what_tty - выводит имя терминала *)

procedure what_tty(fd:longint);

begin

if isatty(fd) then

writeln('fd ',fd,' =>> ', ttyname(fd));

else

writeln ('fd ',fd, ' не является терминалом!');

end;

Упражнение 9.2. Измените процедуру ttyopen предыдущего раздела так, чтобы она возвращала дескриптор файла только для терминалов, а не для дисковых файлов или других типов файлов. Для выполнения проверки используйте функцию isatty. Существуют ли еще какие-либо способы сделать это?

9.3.5. Изменение свойств терминала: структура termios

На уровне оболочки пользователь может вызвать команду stty для изменения свойств дисциплины линии связи терминала. Программа может сделать практически то же самое, используя структуру termios вместе с соответствующими функциями. Обратите внимание, что в более старых системах для этого использовался системный вызов ioctl (сокращение от I/O control – управление вводом/выводом), его применение было описано в первом издании этой книги. Вызов ioctl предназначен для более общих целей и теперь разделен на несколько конкретных вызовов. Совокупность этих вызовов обеспечивает общий программный интерфейс ко всем асинхронным портам связи, независимо от свойств их оборудования.

Структуру termios можно представлять себе как объект, способный описать общее состояние терминала в соответствии с набором флагов, поддерживаемым системой для любого терминального устройства. Точное определение структуры termios будет вскоре рассмотрено. Структуры termios могут заполняться текущими установками терминала при помощи вызова tcgetattr, определенного следующим образом:

Описание

uses linux;

Function TCGetAttr(ttyfd:longint; var tsaved:TermIOS):Boolean;

Эта функция сохраняет текущее состояние терминала, связанного с дескриптором файла ttyfd в структуре tsaved типа termios. Параметр ttyfd должен быть дескриптором файла, описывающим терминал.

Описание

uses linux;

Function TCSetAttr(ttyfd:longint; actions:longint; var tnew:TermIOS):

Boolean;

Вызов tcsetattr установит новое состояние дисциплины связи, заданное структурой tnew. Второй параметр вызова tcsetattr, переменная actions, определяет, как и когда будут установлены новые атрибуты терминала. Существует три возможных варианта, определенных в файле linux:

ТСSANOW

Немедленное выполнение изменений, что может вызвать проблемы, если в момент изменения флагов драйвер терминала выполняет вывод на терминал

TCSADRAIN

Выполняет ту же функцию, что и TCSANOW, но перед установкой новых параметров ждет опустошения очереди вывода

TCSAFLUSH

Аналогично TCSADRAIN ждет, пока очередь вывода не опустеет, а затем также очищает и очередь ввода перед установкой для параметров дисциплины линии связи значений, заданных в структуре tnew

Следующие две функции используют описанные вызовы. Функция tsave сохраняет текущие параметры, связанные с управляющим терминалом процесса, а функция tback восстанавливает последний набор сохраненных параметров. Флаг saved используется для предотвращения восстановления установок функцией tback, если перед этим не была использована функция tsave.

(* Структура tsaved будет содержать параметры терминала *)

var

tsaved:termios;

(* Равно TRUE если параметры сохранены *)

const

saved:boolean=false;

function tsave:boolean;

begin

if isatty(0) and tcgetattr(0,tsaved) then

begin

saved := true;

tsave := true;

exit;

end;

tsave := false;

end;

function tback:boolean; (* Восстанавливает состояние терминала *)

begin

if not isatty(0) or not saved then

tback:=false

else

tback:=tcsetattr(0, TCSAFLUSH, tsaved);

end;

Между этими двумя процедурами может быть заключен участок кода, который временно изменяет состояние терминала, например:

uses linux;

begin

if not tsave then

begin

writeln(stderr, 'Невозможно сохранить параметры терминала');

halt(1);

end;

(* Интересующий нас участок *)

tback;

halt(0);

end.

Соседние файлы в папке Полищук, Семериков. Системное программирование в UNIX средствами Free Pascal