Основы программирования в Linux
$ <b>stty -echo</b>ПримечаниеНе забудьте применить команду
для возврата отображения после ваших экспериментов!stty echoСкорость терминала
Последняя функция, обслуживаемая структурой
, — манипулирование скоростью линии передачи. Для этой скорости не определен отдельный элемент структуры; она управляется вызовами функций. Скорости ввода и вывода обрабатываются отдельно.termiosДалее приведены четыре прототипа вызовов:
<b>#include <termios.h> </b><b>speed_t cfgetispeed(const struct termios *);</b><b>speed_t cfgetospeed(const struct termios *);</b><b>int cfsetispeed(struct termios *, speed_t speed);</b><b>int cfsetospeed(struct termios *, speed_t speed);</b>Обратите внимание на то, что они воздействуют на структуру
, а не непосредственно на порт. Это означает, что для установки новой скорости вы должны считать текущие установки с помощью функцииtermios, задать скорость, применив приведенные вызовы, и затем записать структуруtcgetattrобратно с помощью функцииtermios. Скорость линии передачи изменится только после вызоваtcsetattr.tcsetattrВ вызовах перечисленных функций допускается задание разных значений скорости
, но к основным относятся следующие константы:speed□
— отключение терминала;B0□
— 1200 бод;B1200□
— 2400 бод;B2400□
— 9600 бод;B9600□
— 19 200 бод;B19200□
— 38 400 бод.B38400Не существует скоростей выше 38 400 бод, задаваемых стандартом, и стандартного метода обслуживания последовательных портов на более высоких скоростях.
ПримечаниеВ некоторых системах, включая Linux, для выбора более высоких скоростей определены константы
,В57600иB115200. Если вы пользуетесь более старой версией ОС Linux и эти константы недоступны, можно применить командуВ230400для получения нестандартных скоростей 57 600 и 115 200. В этом случае указанные скорости будут использоваться при выборе константы B38400. Оба эти метода непереносимы, поэтому применяйте их с осторожностью.setserialДополнительные функции
Есть небольшое число дополнительных функций для управления терминалами. Они работают непосредственно с дескрипторами файлов без необходимости считывания и записывания структур типа
.termios<b>#include <termios.h></b><b>int tcdrain(int fd);</b><b>int tcflow(int fd, int flowtype);</b><b>int tcflush(int fd, int in_out_selector);</b>Функции предназначены для следующих целей:
□
— заставляет вызвавшую программу ждать до тех пор, пока не будет отправлен весь поставленный в очередь вывод;tcdrain□
— применяется для приостановки или возобновления вывода;tcflow□
— может применяться для отказа от входных или выходных данных либо и тех, и других.tcflushТеперь, когда мы уделили довольно много внимания структуре
, давайте рассмотрим несколько практических примеров. Возможно, самый простой из них — отключение отображения при чтении пароля (упражнение 5.4). Это делается сбрасыванием флагаtermios.echoУпражнение 5.4. Программа ввода пароля с применениеtermios1. Начните вашу программу password.с со следующих определений:
#include <termios.h>#include <stdio.h>#include <stdlib.h>#define PASSWORD_LEN 8int main() {struct termios initialrsettings, newrsettings;char password[PASSWORD_LEN + 1];2. Далее добавьте строку, считывающую текущие установки из стандартного ввода и копирующую их в только что созданную вами структуру типа
:termiostcgetattr(fileno(stdin), &initialrsettings);3. Создайте копию исходных установок, чтобы восстановить их в конце. Сбросьте флаг
в переменнойECHOи запросите у пользователя его пароль:newrsettingsnewrsettings = initialrsettings;newrsettings.с_lflag &= ~ЕСНО;printf("Enter password: ");4. Далее установите атрибуты терминала в newrsettings и считайте пароль. И наконец, восстановите первоначальные значения атрибутов терминала и выведите пароль на экран, чтобы свести на нет все предыдущие усилия по обеспечению безопасности:
if (tcsetattr(fileno(stdin), TCSAFLUSH, &newrsettings) != 0) {fprintf(stderr, "Could not set attributes\n");} else {fgets(password, PASSWORD_LEN, stdin);tcsetattr(fileno(stdin), TCSANOW, &initialrsettings);fprintf(stdout, "\nYou entered %s\n", password);}exit(0);}Когда вы выполните программу, то увидите следующее:
$ <b>./password</b>Enter password: You entered hello$Как это работает
В этом примере слово
набирается на клавиатуре, но не отображается на экране в строке приглашенияhello. Никакого вывода нет до тех пор, пока пользователь не нажмет клавишу <Enter>.Enter password:Будьте осторожны и изменяйте с помощью конструкции
(которая очищает бит, определенный флагомX&=~FLAGв переменнойFLAG) только те флаги, которые вам нужно изменить. При необходимости можно воспользоваться конструкциейXдля установки одиночного бита, определяемогоX|=FLAG, хотя в предыдущем примере она не понадобилась.FLAG