Настройки termios
по умолчанию включают преобразование некоторых символов в конце строки. Это подходит для модемных линий и терминальных сеансов, но при соединении двух tty повтор преобразования нежелателен. Нежелательно отображать символы новой строки на пару "возврат каретки/перевод строки" при выводе, а также принимаемый возврат каретки — на перевод строки при вводе, поскольку мы уже получаем пары "возврат каретки/перевод строки" с удаленной системы.
194: pts.c_oflag &= ~ONLCR;
195: pts.c_iflag &= ~ICRNL;
Без этих двух строк использование программы robin
для соединения с другим компьютером Linux или Unix приведет к тому, что удаленная система увидит, что вы нажимаете клавишу дважды всякий раз, когда вы нажимаете ее один раз. И всякий раз, когда она будет пытаться отобразить новую строку на вашем экране, вы будете видеть две строки. Поэтому каждый раз при нажатии (предполагая, что у вас получится зарегистрироваться в этих установках терминала) вы увидите отраженные подсказки. Если же вы запустите vi
, то увидите символы ~
, расположенные через строку, а не в каждой строке.
Таким образом, мы внесли в настройки termios
все изменения, которые необходимо сделать перед обработкой аргументов командной строки. Теперь приступим к модификации настроек tty, предоставляющего стандартные входные и выходные данные. Поскольку это один tty, необходимо обработать лишь один файловый дескриптор из пары. Мы отдали предпочтение стандартному вводу, выбрав соглашение, установленное программой stty. И снова все начинается с получения и сохранения атрибутов.
Затем потребуется модифицировать несколько флагов:
201: sts.c_iflag &= ~(BRKINT | ICRNL);
202: sts.c_iflag |= IGNBRK;
203: sts.c_lflag &= ~ISIG;
Отключение BRKINT
играет роль только в том случае, если robin вызывается из регистрационного сеанса, присоединенного к другому последовательному порту, на котором можно получить разрыв. Его отключение означает, что драйвер tty не посылает SIGINT
в robin
, когда в стандартном устройстве ввода robin
возникает разрыв, поскольку robin
не может сделать ничего полезного при получении разрыва. Отключение ICRNL
предотвращает сообщение в robin
о любых символах возврата каретки ( '\r'
) как о символах новой строки ( '\n'
). Как и при отключении BRKINT
это действует лишь тогда, когда сеанс регистрации присоединяется к другому последовательному порту. Также это действует тогда, когда символы возврата каретки не игнорируются (то есть если не установлен флаг IGNCR
).
Функция IGNBRK
заставляет драйвер tty игнорировать разрывы. Включение IGNBRK
будет здесь излишним. При установке IGNBRK
игнорируется BRKINT
. Но не беда, если вы установите обе функции.
Это флаги обработки входных данных. Также модифицируется локальный флаг обработки: отключается ISIG
. Это предотвращает драйвер tty от передачи SIGINT
, SIGQUIT
и SIGTSTP
при получении соответствующего символа ( INTR
, QUIT
или SUSP
). Мы делаем это потому, что хотим переслать эти символы на удаленную систему (или на другое устройство, подключенное к последовательному порту) для последующей обработки там.
Затем следует обработка опций. В некоторых случаях модификаций настроек termios
по умолчанию может оказаться недостаточно, или же, наоборот, слишком много. В таких случаях мы предлагаем некоторые опции командной строки для модификации опций termios
.
По умолчанию мы оставляем последовательный порт в том состоянии управления потоком, в котором мы его находим. Однако в строке 212 есть опции аппаратного управления потоком (использующего управляющие провода CTS и RTS), программного управления потоком (резервирование ^S и ^Q для STOP и START соответственно) и полного отключения управления потоком.
212: case 'h':
213: /* аппаратное управление потоком */
214: pts.c_cflag |= CRTSCTS;
215: pts.c_iflag &= ~(IXON | IXOFF | IXANY);
216: break;
217: case 's' :
218: /* программное управление потоком */
219: pts.c_cflag &= ~CRTSCTS;
220: pts.c_iflag |= IXON | IXOFF | IXANY;
221: break;
222: case 'n':
223: /* отключение управления потоком */
224: pts.q._cflag &= ~CRTSCTS;
225: pts.c_iflag &= ~(IXON | IXOFF | IXANY);
226: break;
Обратите внимание, что программное управление потоком включает три флага.
IXON |
Прекратить пересылать выходные данные при получении символа STOP (обычно ^S) и начать заново при получении символа START (обычно ^Q). |
IXOFF |
Передать символ STOP, когда во входящем буфере накопится слишком много данных. В случае прочтения достаточного количества данных отправите символ START. |
IXANY |
Позволить любому принятому символу, не только START, перезапустить вывод. (Этот флаг обычно реализован в системах Unix, но не определен в POSIX.) |
Когда другая программа использует robin
как вспомогательную, может помешать обработка спецсимволов ( robin
обычно интерпретирует последовательность ^\
), поэтому во избежание такой обработки устанавливается неформатируемый режим. В строке 120 мы предоставляем переменную, определяющую, включен ли неформатируемый режим; по умолчанию этот режим не включается. В строке 140 мы сообщаем popt о том, как информировать, когда в командной строке была указана опция -r
или -raw
, включающая неформатируемый режим.
Читать дальше