Управление драйвером устройства

Опубликовано в Технологии > Серверные технологии Продолжение

Большинство терминалов требует, чтобы операционная система для перемещения курсора к началу следующей строки передавала не только символ перевода строки, но и символ возврата каретки. Символ перевода строки перемещает курсор на одну строку вниз по вертикали, а символ возврата каретки перемещает курсор в начало текущей строки. фотобумага оптом.

С началом выполнения клиент TELNET должен изменить правила работы терминала (например, для того чтобы нажатие клавиши аварийного завершения не приводило к прекращению работы программы, а воспринималось как ввод данных). В клиентской программе вызывается функция операционной системы tcgetattr для получения копии всех параметров драйвера устройства. Затем в ней вызывается системная функция tcsetattr для задания новых параметров. И наконец, прежде чем клиентская программа завершит или приостановит свою работу, в ней вызывается функция tcsetattr для восстановления первоначальных значений параметров. Поэтому, хотя с точки зрения пользователя параметры терминала и назначения некоторых клавиш на время работы клиентской программы становятся иными, они возвращаются к первоначальным значениям после завершения или приостановки работы клиентской программы.

Процедура tcgetattr извлекает текущие параметры из драйвера устройства, связанного с клавиатурой (устройство 0) и сохраняет их в структуре типа termios. Процедура tcsetattr принимает параметры, ранее записанные в структуре termios, и передает их драйверу устройства. Каждая из этих процедур принимает параметры, которые указывают устройство, выполняемую операцию и адрес применяемой структуры.

Установление параметров работы терминала

С началом работы в клиентской программе вызывается процедура ttysetup для установления параметров драйвера терминального устройства. Файл ttysetup.с содержит код:

/* Отмена некоторых специальных символов */
tntty.C_CC[VINTR] = POSIX_VDISABLE?
tntty.c_cc[VQUIT] = ~POSIX_VDISABLE;
tntty.с cc[VSUSP] = POSIX_VDISABLE; tifdef VDSUSP
tntty.c_cc[VDSUSP] = _POSIX_VDISABLE; tendif
if (tcsetattr(0, TCSADRAIN,   tntty) <0)
errexit("can't set tty modes: %s\n", strerror(errno));
}

В процедуре ttysetup вызывается функция tcgetattr для регистрации начальных параметров режима терминала в глобальной переменной oldtty. Поскольку функция tcgetattr позволяет в программе извлекать или загружать сразу все параметры, в клиентской программе нельзя устанавливать каждый параметр отдельно. Для изменения значений одного или нескольких параметров в клиентской программе необходимо создать копию начальных значений параметров в локальной переменной tntty, отредактировать эту копию для изменения одного или нескольких параметров, а затем вызвать функцию tcsetattr для передачи новых параметров драйверу терминального устройства. Изменения, внесенные в процедуре ttysetup, представляют собой отмену действия символов, вызывающих прерывание, завершение работы, приостановку и отсроченную приостановку работы. Фактически установка указанных значений равными _POSIX_VDISABLE исключает для локального драйвера устройства возможность прервать или приостановить работу клиентской программы. Поскольку в процедуре ttysetup эти изменения применяются к копии начальных параметров терминала, эта процедура оставляет все остальные характеристики терминала неизменными. Например, если пользователь определил назначение комбинации клавиш как средство аварийного завершения работы программы, то отмена этой функции в драйвере устройства означает, что клиентская программа сможет читать символ, представляющий комбинацию клавиш , как и любой другой символ. Но поскольку работа процедуры ttysetup начинается с создания копии параметров, то отмена первоначальной интерпретации комбинации клавиш не влияет на другие характеристики терминала (например, на эхо-повтор). Как будет показано ниже, в клиентской программе сохраненная запись с исходными параметрами терминала используется для определения того, какой символ был задан пользователем в качестве сигнала прерывания. Клиент передает серверу команду прерывания при вводе пользователем именно этого символа.