Главная страница  Межпроцессное взаимодействие (состязание) 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 [ 97 ] 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

может внезапно быть сброшена в ноль, если достигается состояние, сигнализирующее о завершении ввода. Когда переменная становится равной нулю, генерируется ответное сообщение процессу, запросившему чтение. Поэтому она также используется как индикатор отправки сообщения. И тогда, когда в начале кода in transfer оказывается, что переменная tp->ttyjnleft уже равна нулю, это вполне веская причина, чтобы прервать выполнение без ответного сообщения.

Во второй части условия сравниваются переменные tp->tty eotct и tp->tty min. В каноническом режиме обе переменные относятся к количеству полных введенных строк, а в неканоническом режиме - имеют отношение к символам. Переменная tp->tty eotct увеличивается на единицу с каждым занесенным во входную очередь переносом строки или байтом и уменьшается подпрофаммой in transfer, когда строка или байт удаляются из очереди. Таким образом, эта переменная подсчитывает количество строк или символов, полученных задачей терминала, но еще не переданных процессу. Поле tp->tty min хранит значение минимального числа строк (в каноническом режиме) или символов (в неканоническом), которое должно быть передано для удовлетворения запроса. В каноническом режиме это значение всегда равно 1, а в неканоническом оно может принадлежать интервалу от О до MAX INPUT (в MINIX эта константа равна 255). Тем самым вторая половина проверки приводит в каноническом режиме к тому, что подпрофамма завершается сразу же, если еще не получена хотя бы одна целая строка. Передача производится после получения всей строки, потому содержимое очереди можно изменить, если, например, пользователь ввел символ KILL или ERASE до нажатия ENTER. В неканоническом режиме немедленный возврат имеет место, если запрошенное количество символов еще недоступно.

Несколькими строками далее переменные tp->ttyjnleft и tp->tty eotct управляют главным циклом процедуры. В каноническом режиме передача производится до тех пор, пока в очереди не останется больше полностью введенных строк. В неканоническом в поле tp->tty eotct подсчитывается количество ожидающих передачи символов. Переменная tp->tty min необходима, чтобы определить, нужно ли входить в цикл, но в определении условия завершения цикла не участвует. После того как цикл начался, передаются либо все полученные символы, либо запрошенное количество, в зависимости от того, что меньше.

V: IN ESC после LNEXT (СМ+ V)

D: IN EOF. конец файла (Ctrl + D)

N: IN EOT, разрыв строки (NL и др.)

сссс: счетчик отображения символов

7: Бит 7, может быть обнулен, если установлен ISTRIP

6-0: Биты 0-6, код ASCII

Рис. 3.27. Поля кода символа, находящегося во входной очереди

Во входной очереди символы представлены в виде 16-разрядных величин. Пользовательскому процессу передаются только младшие 8 бит из 16. Назначе-



ние старших битов кода иллюстрируется рис. 3.27. Здесь есть флаги, показывающие, входит ли символ в ESC-последовательность (CTRL+V), означает ли он конец файла или содержит один из кодов, сопоставленных концу строки.

Четыре бита используются для подсчета символов, чтобы знать, сколько места осталось для вывода эха. Первый из условных операторов внутри цикла проверяет, установлен ли признак конца файла (D на рисунке). Эта проверка делается в начале потому, что символ конца файла не должен ни передаваться программе, ни использоваться при подсчете символов. При передаче каждого символа у него маскируется старший бит, и в локальный буфер записывается только ASCn-зна-чение.

Существует несколько способов сигнализировать об окончании ввода, но от специфической для устройства функции ввода ожидается, что она распознает, когда вводимый символ является переносом строки, CTRL+D или одним из подобных символов, и соответствующим образом отметит их. Функции in transfer остается только проверить эту отметку, бит IN EOT (на рис. 3.27 это N). Если символ опознан, значение tp->tty eotct уменьшается на единицу. В неканоническом режиме подобным образом подсчитываются все символы, и все они отмечаются битом IN EOT, поэтому значение tp->tty eotct уменьшается с каждым полученным символом. Следовательно, единственное различие в работе главного цикла процедуры в двух разных режимах работы терминала можно обнаружить только в последних его строках. Там обнуляется переменная tp->tty eotct, когда получен символ, отмеченный как разрыв строки, но делается это лишь тогда, когда действует канонический режим. Таким образом, когда управление вновь передается в начало цикла, тот корректно завершается после символа разрыва строки. Но сказанное верно только для канонического режима - в неканоническом разрывы строк игнорируются.

Когда цикл завершается, локальный буфер символов для передачи обычно частично полон. В том случае, если tp->ttyjnleft достигла нуля, генерируется и отправляется ответное сообщение. В каноническом режиме это делается всегда, а в неканоническом число символов в буфере сравнивается с минимальным передаваемым количеством, и если символов недостаточно, ответное сообщение не отправляется. Если у вас достаточно хорошая память, чтобы запомнить вызовы in transfer (в do read и handle events), вы, наверно, будете удивлены. Там код, следующий за вызовом, отправлял ответное сообщение, когда in transfer передала больше символов, чем указано в tp->tty min. И здесь именно этот случай. Причина, по которой ответное сообщение не отправляется непосредственно из in transfer, будет раскрыта чуть позже, при обсуждении следующей функции, вызывающей in transfer при других обстоятельствах.

Эта следующая функция носит имя in process. Она вызывается из аппарат-но-зависимого кода для выполнения общих действий, необходимых всегда Ее аргументами являются указатель на структуру tty для исходного устройства, указатель на массив 8-битных символов, подлежащих обработке, и счетчик. Новое значение счетчика возвращается в вызвавшую профамму. Функция in process весьма велика, но ее работа не сложна. Она добавляет 16-разрядные символы во входную очередь, откуда их в дальнейшем извлечет in transfer.



Функцией in transfer символы разделяются на несколько категорий.

1. Нормальные символы, которые добавляются в очередь, расширенные до 16 бит.

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

3. Символы для эхо-отображения применяются немедленно, без занесения в очередь.

4. Символы, имеющие специальное значение, заносятся в очередь с установленными специальными битами, например, такими, как бит EOT.

Сначала рассмотрим совершенно обычную ситуацию, когда совершенно обычный символ, такой как х (ASCII-код 0x78), вводится в середине короткой строки, без влияния ESC-кодов, на терминале, настроенном по умолчанию. Полученный от устройства ввода, этот символ занимает биты от О до 7 на рис. 3.27. В первом условном операторе внутри цикла старший значащий бит сбрасывается в ноль, если установлен бит ISTRIP. Но по умолчанию MINIX не обнуляет старший бит, позволяя вводить 8-битные символы. В любом случае символ х это не затронет. Расширенная обработка ввода по умолчанию в MINIX не разрешена, поэтому проверка бита IEXTERN в переменной tp->tty termios.c lflags делается, но последующие проверки вследствие установленных нами условий (не действует ESC-код, сам символ не является ESC-кодом и это не символ REPRINT) не выполняются.

Проверки в следующих нескольких строках обнаруживают, что символ не является специальным символом POSIX VDISABLE, ни CR, ни NL. Наконец, одна проверка успешна: действует канонический режим, и символ не является специальным. Рассматриваемая нами буква х не является ни символом ERASE, ни KILL, ни EOF (CTRL-I-D), NL или EOL, поэтому первый тест на бит IXON дает отрицательный результат. Этот бит, разрешающий обработку символов START (CTRL-i-S) и STOP (CTRL4-Q), по умолчанию установлен, но х к таковым, очевидно, не относится. Далее обнаруживается, что установлен бит ISIG, разрешающий обработку INTR и QUIT, но, опять же, совпадения в данном случае не обнаруживается.

Фактически первое интересное событие для обычного символа происходит в одной из последних проверок, где выясняется, заполнилась ли уже входная очередь. В этом случае символ игнорируется и, так как активен канонический режим, пользователь не увидит эха символа на экране. Игнорирование символа обеспечивает оператор continue, который вызывает переход в начало цикла. В данном случае рассматриваем рядовые условия выполнения, поэтому предположим, что буфер еще не полон. Не проходит и следующий тест, выделяющий специальный неканонический режим работы. Поэтому управление передается на строку, содержащую вызов функции echo, которая, так как по умолчанию флаг tp-> tty termios.c lflag установлен, показывает пользователю введенный символ.

Наконец, в следующих строках символ подготавливается к занесению во входную очередь. В этот момент увеличивается значение tp->ttyJncount, а tp->tty eotct не изменяется, так как это обычный символ, не отмеченный битом EOT.



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 [ 97 ] 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

© 2000 - 2018 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.