Главная · Поиск книг · Поступления книг · Top 40 · Форумы · Ссылки · Читатели

Настройка текста
Перенос строк


    Прохождения игр    
SCP-381: Pyrotechnic polyphony
Почему нет обещанного видео
Aliens Vs Predator |#6|
Aliens Vs Predator |#5| I'm returning the supercomputer

Другие игры...


liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня
Rambler's Top100
Образование - Сэйдж Рас Весь текст 822.4 Kb

Приемы профессиональной работы в Unix

Предыдущая страница Следующая страница
1 ... 48 49 50 51 52 53 54  55 56 57 58 59 60 61 ... 71
присвоении различных функций разным символам.

     ФАЙЛЫ ТЕРМИНАЛЬНЫХ УСТРОЙСТВ

     Физически адресация терминалов  производится  посредством  файлов
устройств  в  каталоге /dev.  Когда вы регистрируетесь в системе,  вам
присваивается определенный номер терминала, например tty01. Этот номер
терминала в действительности является файлом /dev/tty01. Если вы вызо-
вете команду tty UNIX,  она выведет полное маршрутное имя  файла  того
терминального устройства, за которым вы работаете.

     Файлы терминальных устройств выглядят так же,  как обычные файлы,
за исключением того,  что команда "ls -l" показывает,  как  называются
старший и младший номера устройства,  которые не являются частью обыч-
ных файлов.  Старший номер является индексом в таблице cdevsw[], кото-
рая содержит адрес драйвера устройства, используемого ядром для данно-
го типа устройства. Младший номер идентифицирует конкретное физическое
устройство.  Эти номера появляются в последовательном порядке для всех
устройств,  использующих один и тот же драйвер.  Так выглядит типичный
список файлов устройств в системе XENIX:

---------------------------------------------------------------------------

|
| crw--w--w-   1 russ   tricks  0,  0 Jun 22 02:34 /dev/console
| crw--w--w-   1 russ   tricks  0,  1 Jun 22 00:41 /dev/tty02
| crw--w--w-   1 root   tricks  0,  2 Jun 21 17:56 /dev/tty03
| crw--w--w-   1 root   tricks  0,  3 Jun 21 05:47 /dev/tty04
| crw-rw-rw-   1 root   root    0,  4 Feb 18 17:09 /dev/tty05
| crw-rw-rw-   1 root   root    0,  5 Feb 18 17:09 /dev/tty06
| crw-rw-rw-   2 root   root    5,  0 Jun 21 20:23 /dev/tty11
| crw--w--w-   2 root   tricks  5,  8 Jun 22 02:20 /dev/tty12
| crw-rw-rw-   2 root   root    5,128 Feb 18 17:09 /dev/tty13
| crw-rw-rw-   2 root   root    5,136 Feb 18 17:09 /dev/tty14
|

     По символу 'c' в первом столбце мы видим, что это символьные уст-
ройства,  а биты прав доступа показывают, кто имеет доступ к этим фай-
лам.  Первый столбец чисел (0 или 5) является старшим номером. Младшие
номера в следующем столбце обычно следуют в последовательном  порядке,
но не всегда (как видно в данном примере).

     В дополнение к использованию абсолютного номера вашего терминала,
одно из устройств используется в качестве "логического",  или "родово-
го" адреса вашего терминала. Оно использует другой драйвер устройства,
называется /dev/tty и применяется в случаях,  когда стандартный ввод и
стандартный  вывод  переадресовываются  в  другие файлы,  а прикладной
программе необходимо читать с клавиатуры или писать на экран.  При по-
мощи доступа к файлу /dev/tty образуется связь с самим терминалом. Вы-
бор использования устройства с  именем  tty  вместо  устройства  tty01
главным образом зависит от того,  какая стоит задача. Если вам необхо-
димо  иметь  независимую  от  типа  терминала  программу,  используйте
/dev/tty.

     ПРАВА ДОСТУПА К ТЕРМИНАЛУ

     Поскольку терминальное устройство является файлом,  оно имеет ре-
жимы  прав  доступа точно так же,  как и все другие файлы.  Эти режимы
представляют собой защиту доступа к вашему терминалу. Если все пользо-
ватели  имеют  право  записи  на  ваш  терминал  (это обозначается как
rw--w--w-),  то они могут записать на ваш экран все,  что угодно, и вы
никогда не узнаете,  кто это сделал.  Если вы хотите предупредить это,
то выполните команду "chmod 600 `tty`", где символы ударения и обозна-
чение  tty соответствуют маршрутному имени вашего терминального файла.
Более простой в использовании является команда  UNIX'а  mesg.  Команда
"mesg n" запрещает запись извне на ваш терминал. Ваши собственные про-
цессы по-прежнему имеют доступ на запись.

     Права доступа к терминалу связаны также с проблемой безопасности,
которую  мы  рассмотрим в главе 9.  Пока что отметим,  что всякий раз,
когда вы открываете файл (то ли для чтения,  то ли  для  записи),  вам
возвращается дескриптор файла. Затем вы можете использовать этот деск-
риптор файла в системном вызове  ioctl.  Получение  этого  дескриптора
файла подобно получению ключа к терминальному интерфейсу определенного
пользователя.  Любые изменения,  производимые с помощью ioctl с данным
дескриптором файла,  вызывают немедленный эффект,  и нарушитель защиты
может читать все,  что записывается или считывается с вашего терминала
или даже заставить ваш терминал выполнять команды, которые присваивают
себе неразрешенные права! Пользователь, который работает с этим терми-
налом, может никогда не узнать, что же произошло или кто это сделал.

     Другим примером  подобного  рода  является команда write(1).  Она
используется для установки связи по линии в реальном  режиме  времени,
или  "болтовни".  Она  общается с терминалом путем выполнения записи в
файл устройства.  Измените биты прав  доступа,  выключив  их  командой
"mesg  n",  и никто не сможет выполнить команду write с вашим термина-
лом.  Таким способом вы можете "снять трубку телефона", когда вы хоти-
те, чтобы вам не мешали. Вместе с тем кто-нибудь мог бы сделать такое:

$ while :
> do
>         clear > /dev/tty00
> done &

При этом создается фоновый бесконечный процесс (пока он не будет прек-
ращен командой kill или выходом из системы),  который посылает пользо-
вателю терминала tty00 символы очистки экрана. Как только этот пользо-
ватель что-нибудь набирает на экране, он тут же очищается. Большинство
пользователей не могут даже понять,  что происходит. Если это случится
с вами,  попытайтесь отключить права доступа к вашему терминалу.  Если
же тот, кто это делает, является суперпользователем (root), то никакие
права доступа не смогут остановить его, поскольку суперпользователь не
имеет ограничений по правам доступа к файлам.  В этом случае возникает
проблема для системного администратора!

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

     ОТМЕТКИ О ВРЕМЕНИ ДОСТУПА К ТЕРМИНАЛУ

     Еще одним атрибутом терминалов, который вызван тем, что терминалы
- это файлы,  являются даты модификации,  доступа и обновления. Каждый
файл в системе имеет эти три даты,  которые содержатся в его индексном
дескрипторе (в секундах) в виде ДЛИННЫХ (long) чисел.

     Эти даты могут содержать некоторую интересную информацию. Как бы-
ло  отмечено  при  описании командного файла activ в предыдущей главе,
дата модификации представляет собой последний  момент  времени,  когда
пользователь  что-то  набирал  на  своей клавиатуре.  Другие даты тоже
кое-что означают, но они не так часто используются.

     ОБРАБОТКА ТЕРМИНАЛОМ ВВОДИМОЙ ИНФОРМАЦИИ

     Как уже обсуждалось ранее, по умолчанию драйвер терминала работа-
ет в каноническом режиме, т.е. в режиме построчной обработки. Когда вы
вводите  символы,  драйвер  ожидает,  пока вы нажмете возврат каретки,
после чего передает для обработки всю строку.  Если вы работаете не  в
каноническом  режиме,  то  каждый  символ передается для обработки не-
посредственно после ввода. Наглядным примером такого режима работы яв-
ляется редактор vi.  Вы нажимаете по одной клавише для движения курсо-
ра,  удаления символов и т.д.,  поэтому редактор vi,  очевидно, должен
получать каждый символ сразу же, как только нажата клавиша.

     Каким образом  это  делается  в  программе?  Прием старый и часто
используется в UNIX, хотя и не очень хорошо описан в документации. Та-
кого  рода информацию можно добыть путем просмотра большого количества
текстов программ.  Необходимо отметить, что этот прием лучше всего ра-
ботает в программах на языке Си.  Командные файлы, написанные на языке
shell, могут использовать для этой цели команду stty, но результат бу-
дет не один и тот же.  Следующий фрагмент программы на языке Си отклю-
чает каноническую обработку,  затем читает символы и выводит их на эк-
ран.

1   #include

3   struct termio  tsav, tchg;

5   main (argc, argv)
6   {
7           int c;

9           if (ioctl (0, TCGETA, &tsav) == -1) {
10                  perror("can't get original settings");
                            невозможно получить исходные установки
11                  exit(1);
12          }

14          tchg = tsav;

16          tchg.c_lflag &= ~(ICANON | ECHO);
17          tchg.c_cc[VMIN] = 1;
18          tchg.c_cc[VTIME] = 0;

20          if (ioctl (0, TCSETA, &tchg) == -1) {
21                  perror("can't initiate new settings");
                            невозможно задать новые установки
22          }

24          while (1)
25          {
26                  c = getchar();

28                  if (c == 'x')
29                          break;

31                  putchar(c);
32          }

34          if (ioctl(0, TCSETA, &tsav) == -1) {
35                  perror("can't reset original settings");
                            невозможно вернуть исходные установки
36                  exit(3);
37          }
38  }

     У нас  есть две "терминальные" структуры данных,  одна из которых
содержит исходные установки, а другая - установки, которые мы изменяем
и  записываем.  Первый  системный  вызов  ioctl получает информацию об
установках терминала.  Затем мы присваиваем  эти  значения  изменяемой
структуре (строка 14).  Модификации терминального интерфейса мы выпол-
няем в строках 16-18.  Строка 16 отключает  каноническую  обработку  и
эхо-отображение символов. Строка 17 устанавливает, что минимальное ко-
личество нажатий на клавиши равно одному.  Строка 18  определяет,  что
время ожидания для повторного чтения данных равно 0.  По существу, это
блочное чтение по одному символу.

     Новые значения терминальных характеристик устанавливаются в стро-
ке 20. В этот момент режим работы терминала меняется. Цикл while чита-
ет,  проверяет и выводит символы.  Только при вводе символа x цикл за-
вершается,  терминал  устанавливается  в  первоначальное состояние,  и
программа заканчивает работу.

     Как мы уже заметили,  операция чтения здесь является блочной. Это
значит,  что программа ожидает, пока вы введете символ. Если вы ничего
не вводите,  программа находится в бесконечном цикле  ожидания.  Каким
образом мы изменяем режим чтения с блочного на посимвольный?

     Этот вопрос эквивалентен такому вопросу: "Как опросить клавиатуру
в UNIX?".  Опрос является весьма важным приемом для некоторых примене-
ний. Опрос работает примерно так: "Посмотреть на клавиатуру. Если вве-
ден символ,  получить его и каким-то образом обработать.  В  противном
случае продолжать делать то,  что вы делали. После истечения интервала
времени,  определенного программой, проверить клавиатуру снова." Таким
образом, если пользователь не нажимает на клавиши, программа продолжа-
ет работу, а не ожидает, пока что-нибудь будет нажато на клавиатуре.

     Для выполнения такой работы нам нужно  несколько  более  подробно
рассмотреть терминальный интерфейс.  Как было отмечено ранее, терминал
представляет собой файл.  Это значит,  что он  должен  обладать  всеми
обычными свойствами файлов - возможностью открытия,  закрытия, чтения,
записи и т.д.  Мы также видели,  что терминалы имеют протокол  работы,
который может быть изменен командой stty. Мы видели, что для получения
одного символа с клавиатуры используется протокол  работы.  Теперь  мы
увидим,  что для выполнения опроса вы должны использовать технику, ко-
торая относится к файлам, а не ioctl.

     Секрет здесь в том,  чтобы открыть терминальный файл, изменяя ре-
жим его открытия.  Затем для получения одного символа используется тот
Предыдущая страница Следующая страница
1 ... 48 49 50 51 52 53 54  55 56 57 58 59 60 61 ... 71
Ваша оценка:
Комментарий:
  Подпись:
(Чтобы комментарии всегда подписывались Вашим именем, можете зарегистрироваться в Клубе читателей)
  Сайт:
 
Комментарии (52)

Реклама