TTY-абстракция

Поделись знанием:
Перейти к: навигация, поиск

Подсистема TTY, или TTY-абстракция — это одна из основ UNIX-систем, в частности Linux.





История

В 1869 году был изобретён тикерный аппарат — специальный телеграфный аппарат для передачи котировок ценных бумаг. Постепенно это устройство эволюционировало в телетайп — более быстрый прибор, основанный на таблице символов ASCII. Одно время телетайпы всего мира даже были соединены в единую сеть под названием Telex, адресация в которой осуществлялась на том же принципе вращающегося вала с искателями, что и в механических автоматических телефонных станциях того времени. Сеть Telex использовалась для передачи коммерческих телеграмм. Однако в то время телетайпы пока не подключались к компьютерам.

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

Так как различных моделей телетайпов было множество, потребовался некий уровень программной совместимости, чтобы абстрагироваться от конкретной модели телетайпа. В UNIX и UNIX-подобных системах низкоуровневая работа с телетайпом — например, количество бит в пакете, скорость в бодах, контроль потока, контроль чётности, специальные коды для зачаточного форматирования страницы, и т. д., — возлагалась на ядро операционной системы. Такие возможности, как перемещение курсора, цветной текст и т. п., стали возможны лишь в конце 1970-х годов, с появлением видеотерминалов типа VT-100. Все эти расширенные функции оставались на попечении приложений.

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

Сценарий использования

Предположим, пользователь набирает текст на телетайпе, и читает ответ компьютера, который тот печатает. Телетайп при этом используется как физический (реальный) терминал. Терминал этот подключается к компьютеру при помощи универсального последовательного асинхронного порта. Операционная система имеет драйвер порта, который отвечает за физическую передачу байтов по проводам (контроль чётности, контроль потока и т. п.). В простейшем случае этот драйвер может просто передавать данные использующему его приложению. Но при этом не будет следующих функций:

Редактирование строк

Большинство пользователей допускают опечатки по время набора текста, так что клавиша забоя очень важна. Конечно, можно было бы воплотить её функциональность в самой программе, использующей телетайп. Однако в соответствии с философией UNIX, программы должны быть как можно проще. Поэтому операционная система сама предоставляет буфер для редактирования текста, а также некоторые простейшие команды редактирования — «удалить символ», «удалить слово», «удалить строку». Все эти функции реализованы в модуле дисциплины линии (line discipline). По умолчанию они включены; такой режим называется каноническим (canonical), или приготовленным (cooked). Программа при желании может отключить эти функции, переведя драйвер в сырой (raw) режим. (Большинство современных интерактивных программ — текстовые редакторы, почтовые агенты, оболочки, а также все программы, использующие Curses или Readline, — работают в raw-режиме, и сами обрабатывают все команды редактирования). Упомянутый слой протокола также позволяет настраивать эхо (отображение набираемых символов на этом же самом терминале), автоматическую конвертацию признаков конца строки и возврата каретки, и т. п. Таким образом, слой протокола является примитивным разборщиком текста типа Sed, причём работающим в режиме ядра.

Смысл выделения описанной выше обработки в отдельный слой заключается в том, что дисциплину (то есть конкретный драйвер этого слоя) можно динамически менять. Например, вместо дисциплины терминала можно включить дисциплину передачи данных с пакетной коммутацией — ppp, IrDA, последовательную мышь и т. д.

Управление сеансами связи[en]

Как правило, пользователь хочет запустить одновременно несколько программ, и взаимодействовать с ними по очереди. Если программа зависает, — пользователь наверняка захочет аварийно завершить (англ.) её. Процессы, работающие в фоновом режиме, должны блокироваться, как только они захотят вывести какой-либо текст на экран. Аналогичным образом набираемый пользователем текст должен передаваться только активной в данный момент программе. Операционная система реализует все эти функции при помощи драйвера TTY.

Как уровень дисциплины (протокола), так и драйвер TTY являются пассивными. Иными словами, они не могут сами предпринимать каких-либо действий, а являются лишь набором процедур, которые могут быть вызваны другими процедурами. В отличие от них, сама операционная система является процессом, то есть имеет свой собственный контекст.

Система из драйвера UART-порта, дисциплины (протокола) и драйвера TTY называется устройством TTY, или просто TTY. Пользовательский процесс может изменять поведение любого TTY-устройства путём манипулирования соответствующим ему файлом (англ.) в папке /dev. Естественно, для этого данный процесс должен обладать правами записи (англ.) в этот файл. Поэтому, когда пользователь входит в систему (англ.) и подключается к определённому TTY, этот пользователь должен стать владельцем файла, соответствующего этому TTY. Именно это и делает программа login. (Сама программа login запускается от имени суперпользователя).

При этом нужно помнить, что в качестве физической линии, соединяющей терминал с компьютером, вполне может выступать и телефонная линия, что позволяет практически неограниченно удалить терминал от компьютера. С точки зрения операционной системы, единственным отличием этого случая от простого подключения терминала по UART-порту будет необходимость обрабатывать сигнал «трубка повешена», который может вдруг прийти от модема.

Теперь рассмотрим случай, когда система работает на обычном современном персональном компьютере. Дисциплина и TTY-драйвер работают так же, как и раньше, но драйвера UART-порта уже нет, так как нет телетайпа, который бы через него подключался. Вместо него используется эмулятор видеотерминала — программа, которая имитирует видеотерминал (аналог телетайпа, но с видеоэкраном вместо бумажной ленты), и отображает содержимое этого терминала на экран. При этом эта программа, в отличие от консоли, уже работает в пространстве пользователя (англ.), а не ядра, что обеспечивает куда большую гибкость; например, можно выводить терминал в окне, как это делает Xterm и его многочисленные клоны.

Для того, чтобы позволить работу эмулятора терминала в пространстве пользователя, и при этом не отказываться от всей вышеописанной подсистемы TTY, был изобретён так называемый Pseudo Terminal (англ.), или PTY. Псевдотерминал может быть запущен внутри другого псевдотерминала; так поступают, например, Screen или Ssh.

Место TTY в модели процессов

Процесс в ОС Linux может находиться в одном из следующих состояний:

  • R (running/runnable) — процесс исполняется либо ожидает своей очереди исполняться;
  • D — непрерываемый сон — процесс ожидает определённого события;
  • S — прерываемый сон — процесс ожидает определённого события либо сигнала;
  • T — остановка — процесс приостановлен, например, отладчиком;
  • Z (zombie) — процесс уже завершился, но ещё не передал родительскому процессу свой код возврата.

При помощи команды ps l можно увидеть статус каждого процесса, причём в колонке WCHAN будет отображено событие, которого дожидается конкретный спящий процесс.

$ ps l
F   UID   PID  PPID PRI  NI    VSZ   RSS WCHAN  STAT TTY        TIME COMMAND
0   500  5942  5928  15   0  12916  1460 wait   Ss   pts/14     0:00 -/bin/bash
0   500 12235  5942  15   0  21004  3572 wait   S+   pts/14     0:01 vim index.php
0   500 12580 12235  15   0   8080  1440 wait   S+   pts/14     0:00 /bin/bash -c (ps l) >/tmp/v727757/1 2>&1
0   500 12581 12580  15   0   4412   824 -      R+   pts/14     0:00 ps l

Как видно, несколько процессов совершили системный вызов wait (англ.), и теперь дожидаются, когда произойдёт смена состояния одного из их дочерних процессов. Сон может быть прерываемым и непрерываемым. Прерываемый сон означает, что хотя процесс находится в очереди ожидания, он может быть запущен при получении сигнала. Все процедуры операционной системы, связанные с ожиданием того или иного события, после возвращения функции schedule() обязаны проверять, нет ли необработанного сигнала, и если есть — прерывать системный вызов.

Колонка STAT в выводе команды ps показывает состояние процесса, но она также может содержать несколько флагов:

  • s — данный процесс — ведущий процесс сессии;
  • + — данный процесс входит в группу процессов, с которыми в данный момент идёт работа пользователя (то есть foreground processes — в противоположность background processes, работающим в фоновом режиме).

Именно эти атрибуты и используются для управления заданиями.

Управление заданиями и сессиями

Пусть пользователь нажал ^Z при работе с программой, или запустил программу с префиксом &, чтобы она заработала в фоновом режиме. При этом включается механизм управления заданиями.

«Задание» — это, практически, синоним «группы процессов». Пользователь может манипулировать заданиями внутри данной сессии[en] при помощи встроенных команд оболочки, таких, как jobs, fg или bg. В свою очередь, каждая сессия управляется ведущим процессом сессии — оболочкой, которая активно общается с ядром при помощи сложного протокола, состоящего из системных вызовов и сигналов.

Рассмотрим взаимоотношения процессов, заданий и сессий на примере:

Смысл в том, что каждый конвейер — это задание, потому что все процессы в конвейере должны управляться (то есть останавливаться, возобновляться или завершаться) одновременно. Именно поэтому команда kill позволяет посылать сигналы сразу целым группам процессов.

Команда fork по умолчанию помещает свежесозданный процесс в ту же группу процессов, в которой находится его родитель, поэтому, например, нажатие ^C на клавиатуре повлияет и на дочерний процесс, и на родителя. С другой стороны, оболочка, являясь ведущим процессом сессии, автоматически создаёт новую группу процессов каждый раз, когда сталкивается с необходимостью запустить очередной конвейер. Задача драйвера TTY — отслеживать идентификатор активной группы процессов (который явно обновляется ведущим процессом сессии), а также размер подключённого терминала (который явно обновляется эмулятором терминала либо самим пользователем).

Хотя несколько процессов могут одновременно иметь один и тот же псевдотерминал в качестве своего стандартного ввода и/или стандартного вывода, только активное (foreground) задание будет получать на вход текст, вводимый с TTY, и будет иметь право само выводить информацию на него. Если процесс, не являющийся активным, хочет вывести что-то на экран, ядро приостанавливает его при помощи сигнала.

TTY и система сигналов

Рассмотрим взаимодействие различных составляющих TTY с программами в пространстве пользователя.

Как известно, во все файлы устройств, включая файлы устройств TTY, можно читать и писать, а также настраивать их при помощи универсального системного вызова ioctl (англ.). Однако системный вызов ioctl должен быть вызван самим процессом, поэтому он не позволяет ядру асинхронно общаться с приложением. Для таких случаев есть система сигналов.

Система сигналов — довольно грубый способ взаимодействия. Дело в том, что, хотя процессы могут перехватывать сигналы и обрабатывать их, абсолютное большинство процессов этого не делает. В результате активируется обработчик по умолчанию, который, как правило, приводит к прекращению работы программы (иногда с созданием дампа памяти). Кроме того, для обработки сигналов нет общих чётких правил, и каждый сигнал приходится рассматривать по отдельности.

Список всех сигналов доступен при помощи команды kill -l.

Конкретно к TTY имеют непосредственное отношение следующие сигналы:

SIGHUP

Действие по умолчанию: прекратить выполнение программы

Возможные действия: прекратить выполнение программы, вызвать функцию, или ничего не делать

Драйвер UART-порта посылает сигнал SIGHUP всей сессии, когда модем переходит в состояние «трубка повешена». Обычно это убивает все процессы сессии. Некоторые программы, такие, как Screen или Nohup, отделяются от своей сессии и своего TTY, поэтому их дочерние процессы не умирают при отключении модема.

SIGINT

Действие по умолчанию: прекратить выполнение программы

Возможные действия: прекратить выполнение программы, вызвать функцию, или ничего не делать

Сигнал SIGINT генерируется драйвером TTY, когда во входном потоке появляется особый символ ^C (ASCII-код этого символа равен 3). Драйвер посылает этот сигнал активному заданию. Программа, имеющая доступ к TTY, может изменить код этого спецсимвола, либо вообще отключить генерацию этого сигнала. Менеджер сессий отслеживает настройки TTY, установленные каждой из работающих задач, и применяет их, когда эти задачи переключаются.

SIGQUIT

Действие по умолчанию: выход с дампом памяти ядра

Возможные действия: выйти с дампом памяти ядра, вызвать функцию, или ничего не делать

SIGQUIT аналогичен SIGINT, но Действие по умолчанию другое, и спецсимвол другой (обычно ^\).

SIGPIPE

Действие по умолчанию: прекратить выполнение программы

Возможные действия: прекратить выполнение программы, вызвать функцию, или ничего не делать

Ядро посылает сигнал SIGPIPE процессу, который пытается писать данные в конвейер, из которого никто не читает. Этот сигнал очень полезен, потому что он позволяет конструкции типа yes | head нормально отработать и завершиться, а не зависнуть.

SIGCHLD

Действие по умолчанию: ничего не делать

Возможные действия: вызвать функцию, или ничего не делать

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

SIGSTOP

Действие по умолчанию: приостановить работу

Возможные действия: приостановить работу

Этот сигнал приостанавливает исполнение процесса, который его получает. Его нельзя перехватить. Как правило, ядро не использует этот сигнал. Вместо него спецсимвол ^Z посылает сигнал SIGTSTP, который уже может быть отловлен приложением; как правило, приложение выполняет определённые действия, после чего само себя ставит на паузу — уже сигналом SIGSTOP.

SIGCONT

Действие по умолчанию: пробудиться

Возможные действия: пробудиться и, при желании, вызвать функцию

Этот сигнал пробуждает усыплённый ранее процесс. Его посылает оболочка, когда пользователь вызывает команду fg. Так как этот сигнал нельзя отловить, неожиданный сигнал SIGCONT означает, что процесс был приостановлен, а затем пробудился.

SIGTSTP

Действие по умолчанию: приостановить работу

Возможные действия: приостановить работу, вызвать функцию, или ничего не делать

SIGTSTP аналогичен SIGINT и SIGQUIT, но Действие по умолчанию другое, и спецсимвол другой (обычно ^Z, ASCII-код 26).

SIGTTIN

Действие по умолчанию: приостановить работу

Возможные действия: приостановить работу, вызвать функцию, или ничего не делать

Когда процесс, выполняющийся в фоновом режиме, пытается читать из TTY, TTY посылает этот сигнал всему заданию. Обычно это приостанавливает задание, до тех пор пока пользователь не переключится на него и не сможет ввести ожидаемые данные.

SIGTTOU

Действие по умолчанию: приостановить работу

Возможные действия: приостановить работу, вызвать функцию, или ничего не делать

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

SIGWINCH

Действие по умолчанию: ничего не делать

Возможные действия: вызвать функцию, или ничего не делать

Как уже упоминалось, TTY отслеживает размер терминала, однако информацию о нём нужно обновлять вручную. Для этого TTY посылает сигнал SIGWINCH активному заданию. Хорошо написанные программы, типа текстовых редакторов, адекватно реагируют на этот сигнал: узнают от TTY новый размер терминала и перерисовывают содержимое окна, чтобы оно выглядело соответствующе.

Пример

Рассмотрим следующий пример. Пусть пользователь редактирует текст в консольном текстовом редакторе. Курсор примерно посередине экрана, и редактор как раз занят выполнением задачи, требующей много процессорного времени (например, поиском и заменой слов в большом файле). В этот момент пользователь нажимает ^Z.

Так как дисциплина (протокол линии связи) была настроена на отлов этого символа, пользователю не придётся ждать, пока редактор закончит выполнение текущего задания, потому что слой дисциплины мгновенно пошлёт сигнал SIGTSTP активной задаче (то есть активной группе процессов). Причём в эту группу входит не только сам редактор, но и все его дочерние процессы.

Пусть редактор настроил ручную обработку сигнала SIGTSTP. Тогда ядро вызывает обработчик прерывания (внутри процесса текстового редактора). Этот обработчик передвигает курсор на последнюю строку на экране, путём записи определённой последовательности управляющих символов в TTY. Так как редактор является активным процессом, эти символы незамедлительно передаются и обрабатываются. Затем редактор посылает сам себе (и своей группе процессов) сигнал SIGSTOP и засыпает.

Тот факт, что текстовый редактор уснул, передаётся ведущему процессу сессии при помощи сигнала SIGCHLD (вместе с идентификаторами уснувших процессов). Когда засыпают все процессы активной задачи, ведущий процесс сессии запоминает текущие настройки TTY, и провозглашает себя активной задачей данного TTY при помощи системного вызова ioctl. После этого он печатает на экране уведомление для пользователя, что текущая задача была приостановлена.

Если сейчас вызвать команду ps, она покажет, что текстовый редактор приостановлен (буква «T»). При попытке пробудить его — например, встроенной в оболочку командой bg, или же командой kill послав ему сигнал SIGCONT, — редактор запустит обработчик сигнала SIGCONT. Этот обработчик попытается перерисовать интерфейс путём записи последовательности управляющих символов в TTY. Однако теперь редактор — фоновый процесс, поэтому вместо отрисовки интерфейса TTY пошлёт редактору сигнал SIGTTOU, и тот опять уснёт. Ведущий процесс сессии узнает об этом при помощи сигнала SIGCHLD, и опять выведет на экран уведомление для пользователя.

Если же вместо этого вызвать команду fg, оболочка восстановит сохранённые ранее настройки TTY, вновь сделает редактор активной задачей, и пошлёт ему (и его группе процессов) сигнал SIGCONT. После этого редактор сможет нормально отрисовать свой интерфейс, и работа продолжится.

Контроль потока и блокировка ввода-вывода

Рассмотрим пример: пользователь вводит в Xterm команду yes. После этого в окне Xterm появляется множество букв y. Естественно, программа yes генерирует буквы y значительно быстрее, чем Xterm способен их принимать, обновлять свой кадровый буфер, вызывать процедуры отрисовки в X-сервере, и т. д.

Чтобы сделать возможной работу в таких условиях, применяется блокировка ввода-вывода. Буфер псевдотерминала, расположенный в пространстве ядра, имеет очень ограниченный объём, и когда он забьётся буквами y, генерируемыми программой yes, очередной системный вызов write, осуществлённый этой программой, будет заблокирован. Программа yes перейдёт в режим прерываемого сна, до тех пор пока Xterm не сможет хотя бы частично освободить буфер псевдотерминала.

Аналогичная ситуация возникнет и в случае, если TTY подключён к последовательному порту. Если программа заполнит буфер, очередной её системный вызов write заблокирует процесс. При желании TTY можно открыть в неблокируемом режиме при помощи флага O_NONBLOCK; тогда вместо блокировки системный вызов write вернёт ошибку EAGAIN.

Однако даже если в буфере ядра ещё есть место, процесс можно заблокировать. Рассмотрим, например, такую ситуацию: к компьютеру подключён старый видеотерминал VT-100, общающийся с ним на частоте 9600 бод. Пусть компьютер только что послал терминалу сложную последовательность управляющих символов, требуя пролистать текст на экране вверх или вниз. Подобная задача сильно загружает терминал, и он становится неспособен обрабатывать поступающие данные со скоростью 9600 бод (хотя сам его UART-порт, естественно, может и дальше общаться с компьютером на этой скорости). В результате внутренний буфер терминала скоро переполнится. Поэтому на время работы терминала следует заблокировать TTY.

Для этого, как и для многих других сигналов, используются спецсимволы. Например, как уже упоминалось выше, байт ^C не передаётся приложению, когда оно читает данные системным вызовом read, а вместо этого вызывает сигнал SIGINT, который передаётся активному заданию. Аналогичным образом работают байты ^S (ASCII-код 19), который блокирует TTY, и ^Q (ASCII-код 17), который его пробуждает. Старые текстовые терминалы автоматически передают эти байты, основываясь на объёме оставшегося свободного места в своих буферах. Это называется программным контролем потока (в отличие от аппаратного, при котором TTY приостанавливается при помощи сигнала на специально выделенной для этого линии). Именно по этой причине Xterm блокируется, если случайно нажать ^S.

Необходимо различать два случая:

  • Попытка записи в TTY, заблокированный контролем потока либо переполнением буфера ядра, приведёт к блокировке данного процесса;
  • Попытка записи в TTY во время работы в фоновом режиме приведёт к усыплению всей группы процессов.

Настройка TTY

Узнать TTY, который контролирует данную программную оболочку, можно при помощи утилиты tty.

Открытый TTY можно настроить при помощи ioctl. Однако, данный интерфейс не является переносимым, поэтому рекомендуется использовать вместо него POSIX-совместимые обёртки (см. man 3 termios).

TTY можно также настроить прямо из консоли, используя утилиту stty, которая основана на упомянутом выше API termios:

$ stty -a
speed 38400 baud; rows 73; columns 238; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke

stty -a выводит все настройки TTY. Конкретный TTY можно выбрать при помощи флага -F.

speed показывает скорость UART-порта. Псевдотерминалы игнорируют это значение.

rows и columns показывают размер терминала в символах. По сути, это просто две числовые переменные внутри TTY-драйвера, которые можно свободно читать и изменять. При их изменении активной задаче будет послан сигнал SIGWINCH.

line показывает номер активной дисциплины. Все имеющиеся в системе дисциплины перечислены в /proc/tty/ldiscs.

Далее перечисляются спецсимволы, а в конце — выбранные в настоящий момент опции. Тире означает, что опция отключена.

Примеры

Если открыть окно Xterm, запомнить его TTY (вызвав команду tty) и размер (вызвав команду stty -a), запустить полноэкранное консольное приложение (типа vim), а потом в другом окне Xterm набрать
stty -F X rows Y
, где X — имя TTY первого окна, а Y — половина его высоты, то vim в первом окне тут же получит сигнал SIGWINCH, и перерисует свой интерфейс, используя лишь половину предоставленного ему окна. Если в окне Xterm набрать
stty intr o
, то теперь сигнал SIGINT будет генерироваться при вводе символа «o». При этом нажатие ^C ни к чему не приведёт. Иногда в UNIX-системе не работает кнопка backspace. Это происходит потому, что эмулятор терминала посылает в TTY не тот ASCII-код, которому в этом TTY назначена функция erase. Чтобы решить эту проблему, нужно набрать
stty erase ^H
или
stty erase ^?
. Первая команда установит символ стирания на ASCII-код 8, вторая — на 127. На приложения, работающие в сыром режиме, эти настройки не влияют. Если в окне Xterm набрать
stty -icanon
, это отключит канонический режим. Если после этого попытаться, например, запустить программу cat, все сочетания клавиш, отвечающие за редактирование текста, такие, как ^U или даже backspace, не будут работать. Кроме того, cat будет получать (и, соответственно, выводить) данные не строчками, как раньше, а отдельными символами. Если в окне Xterm набрать
stty -echo
, это отключит вывод на экран набираемых данных. Вызов после этого программы cat продемонстрирует, что набираемые на клавиатуре данные больше не выводятся на экран (то есть придётся набирать текст «вслепую»). Однако, после нажатия клавиши Enter, ядро передаст последнюю напечатанную строчку программе cat, и она уже выведет её на экран. Если в окне Xterm набрать
stty -tostop
, это позволит процессам, работающим в фоновом режиме, выводить данные на экран, вместо того чтобы быть заблокированными. Например, команда
(sleep 5; echo hello, world) &
покажет приглашение оболочки, однако через 5 секунд в консоль будет выведена строчка «hello, world». Если в это время работать с терминалом (например, набирать какой-то текст), то эта строчка вклинится прямо в этот набираемый текст. Если же набрать
stty tostop
, то запуск команды
(sleep 5; echo hello, world) &
приведёт к блокировке этого процесса сигналом SIGTTOU, потому что через 5 секунд он попытается вывести на экран текст, находясь при этом в фоновом режиме. Обычно оболочка в таких случаях выводит на экран предупреждающую надпись (либо сразу же, либо при выводе очередного приглашения). Команда
stty sane
возвращает настройки TTY к «вменяемым» параметрам.

Больше информации можно найти в системе info (англ.) (info libc, «Job Control»).

Напишите отзыв о статье "TTY-абстракция"

Ссылки

  • [www.linusakesson.net/programming/tty/index.php The TTY demystified]

Отрывок, характеризующий TTY-абстракция

1 2 3 4 5 6 7 8 9 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160
Написав по этой азбуке цифрами слова L'empereur Napoleon [император Наполеон], выходит, что сумма этих чисел равна 666 ти и что поэтому Наполеон есть тот зверь, о котором предсказано в Апокалипсисе. Кроме того, написав по этой же азбуке слова quarante deux [сорок два], то есть предел, который был положен зверю глаголати велика и хульна, сумма этих чисел, изображающих quarante deux, опять равна 666 ти, из чего выходит, что предел власти Наполеона наступил в 1812 м году, в котором французскому императору минуло 42 года. Предсказание это очень поразило Пьера, и он часто задавал себе вопрос о том, что именно положит предел власти зверя, то есть Наполеона, и, на основании тех же изображений слов цифрами и вычислениями, старался найти ответ на занимавший его вопрос. Пьер написал в ответе на этот вопрос: L'empereur Alexandre? La nation Russe? [Император Александр? Русский народ?] Он счел буквы, но сумма цифр выходила гораздо больше или меньше 666 ти. Один раз, занимаясь этими вычислениями, он написал свое имя – Comte Pierre Besouhoff; сумма цифр тоже далеко не вышла. Он, изменив орфографию, поставив z вместо s, прибавил de, прибавил article le и все не получал желаемого результата. Тогда ему пришло в голову, что ежели бы ответ на искомый вопрос и заключался в его имени, то в ответе непременно была бы названа его национальность. Он написал Le Russe Besuhoff и, сочтя цифры, получил 671. Только 5 было лишних; 5 означает «е», то самое «е», которое было откинуто в article перед словом L'empereur. Откинув точно так же, хотя и неправильно, «е», Пьер получил искомый ответ; L'Russe Besuhof, равное 666 ти. Открытие это взволновало его. Как, какой связью был он соединен с тем великим событием, которое было предсказано в Апокалипсисе, он не знал; но он ни на минуту не усумнился в этой связи. Его любовь к Ростовой, антихрист, нашествие Наполеона, комета, 666, l'empereur Napoleon и l'Russe Besuhof – все это вместе должно было созреть, разразиться и вывести его из того заколдованного, ничтожного мира московских привычек, в которых, он чувствовал себя плененным, и привести его к великому подвигу и великому счастию.
Пьер накануне того воскресенья, в которое читали молитву, обещал Ростовым привезти им от графа Растопчина, с которым он был хорошо знаком, и воззвание к России, и последние известия из армии. Поутру, заехав к графу Растопчину, Пьер у него застал только что приехавшего курьера из армии.
Курьер был один из знакомых Пьеру московских бальных танцоров.
– Ради бога, не можете ли вы меня облегчить? – сказал курьер, – у меня полна сумка писем к родителям.
В числе этих писем было письмо от Николая Ростова к отцу. Пьер взял это письмо. Кроме того, граф Растопчин дал Пьеру воззвание государя к Москве, только что отпечатанное, последние приказы по армии и свою последнюю афишу. Просмотрев приказы по армии, Пьер нашел в одном из них между известиями о раненых, убитых и награжденных имя Николая Ростова, награжденного Георгием 4 й степени за оказанную храбрость в Островненском деле, и в том же приказе назначение князя Андрея Болконского командиром егерского полка. Хотя ему и не хотелось напоминать Ростовым о Болконском, но Пьер не мог воздержаться от желания порадовать их известием о награждении сына и, оставив у себя воззвание, афишу и другие приказы, с тем чтобы самому привезти их к обеду, послал печатный приказ и письмо к Ростовым.
Разговор с графом Растопчиным, его тон озабоченности и поспешности, встреча с курьером, беззаботно рассказывавшим о том, как дурно идут дела в армии, слухи о найденных в Москве шпионах, о бумаге, ходящей по Москве, в которой сказано, что Наполеон до осени обещает быть в обеих русских столицах, разговор об ожидаемом назавтра приезде государя – все это с новой силой возбуждало в Пьере то чувство волнения и ожидания, которое не оставляло его со времени появления кометы и в особенности с начала войны.
Пьеру давно уже приходила мысль поступить в военную службу, и он бы исполнил ее, ежели бы не мешала ему, во первых, принадлежность его к тому масонскому обществу, с которым он был связан клятвой и которое проповедывало вечный мир и уничтожение войны, и, во вторых, то, что ему, глядя на большое количество москвичей, надевших мундиры и проповедывающих патриотизм, было почему то совестно предпринять такой шаг. Главная же причина, по которой он не приводил в исполнение своего намерения поступить в военную службу, состояла в том неясном представлении, что он l'Russe Besuhof, имеющий значение звериного числа 666, что его участие в великом деле положения предела власти зверю, глаголящему велика и хульна, определено предвечно и что поэтому ему не должно предпринимать ничего и ждать того, что должно совершиться.


У Ростовых, как и всегда по воскресениям, обедал кое кто из близких знакомых.
Пьер приехал раньше, чтобы застать их одних.
Пьер за этот год так потолстел, что он был бы уродлив, ежели бы он не был так велик ростом, крупен членами и не был так силен, что, очевидно, легко носил свою толщину.
Он, пыхтя и что то бормоча про себя, вошел на лестницу. Кучер его уже не спрашивал, дожидаться ли. Он знал, что когда граф у Ростовых, то до двенадцатого часу. Лакеи Ростовых радостно бросились снимать с него плащ и принимать палку и шляпу. Пьер, по привычке клубной, и палку и шляпу оставлял в передней.
Первое лицо, которое он увидал у Ростовых, была Наташа. Еще прежде, чем он увидал ее, он, снимая плащ в передней, услыхал ее. Она пела солфеджи в зале. Он внал, что она не пела со времени своей болезни, и потому звук ее голоса удивил и обрадовал его. Он тихо отворил дверь и увидал Наташу в ее лиловом платье, в котором она была у обедни, прохаживающуюся по комнате и поющую. Она шла задом к нему, когда он отворил дверь, но когда она круто повернулась и увидала его толстое, удивленное лицо, она покраснела и быстро подошла к нему.
– Я хочу попробовать опять петь, – сказала она. – Все таки это занятие, – прибавила она, как будто извиняясь.
– И прекрасно.
– Как я рада, что вы приехали! Я нынче так счастлива! – сказала она с тем прежним оживлением, которого уже давно не видел в ней Пьер. – Вы знаете, Nicolas получил Георгиевский крест. Я так горда за него.
– Как же, я прислал приказ. Ну, я вам не хочу мешать, – прибавил он и хотел пройти в гостиную.
Наташа остановила его.
– Граф, что это, дурно, что я пою? – сказала она, покраснев, но, не спуская глаз, вопросительно глядя на Пьера.
– Нет… Отчего же? Напротив… Но отчего вы меня спрашиваете?
– Я сама не знаю, – быстро отвечала Наташа, – но я ничего бы не хотела сделать, что бы вам не нравилось. Я вам верю во всем. Вы не знаете, как вы для меля важны и как вы много для меня сделали!.. – Она говорила быстро и не замечая того, как Пьер покраснел при этих словах. – Я видела в том же приказе он, Болконский (быстро, шепотом проговорила она это слово), он в России и опять служит. Как вы думаете, – сказала она быстро, видимо, торопясь говорить, потому что она боялась за свои силы, – простит он меня когда нибудь? Не будет он иметь против меня злого чувства? Как вы думаете? Как вы думаете?
– Я думаю… – сказал Пьер. – Ему нечего прощать… Ежели бы я был на его месте… – По связи воспоминаний, Пьер мгновенно перенесся воображением к тому времени, когда он, утешая ее, сказал ей, что ежели бы он был не он, а лучший человек в мире и свободен, то он на коленях просил бы ее руки, и то же чувство жалости, нежности, любви охватило его, и те же слова были у него на устах. Но она не дала ему времени сказать их.
– Да вы – вы, – сказала она, с восторгом произнося это слово вы, – другое дело. Добрее, великодушнее, лучше вас я не знаю человека, и не может быть. Ежели бы вас не было тогда, да и теперь, я не знаю, что бы было со мною, потому что… – Слезы вдруг полились ей в глаза; она повернулась, подняла ноты к глазам, запела и пошла опять ходить по зале.
В это же время из гостиной выбежал Петя.
Петя был теперь красивый, румяный пятнадцатилетний мальчик с толстыми, красными губами, похожий на Наташу. Он готовился в университет, но в последнее время, с товарищем своим Оболенским, тайно решил, что пойдет в гусары.
Петя выскочил к своему тезке, чтобы переговорить о деле.
Он просил его узнать, примут ли его в гусары.
Пьер шел по гостиной, не слушая Петю.
Петя дернул его за руку, чтоб обратить на себя его вниманье.
– Ну что мое дело, Петр Кирилыч. Ради бога! Одна надежда на вас, – говорил Петя.
– Ах да, твое дело. В гусары то? Скажу, скажу. Нынче скажу все.
– Ну что, mon cher, ну что, достали манифест? – спросил старый граф. – А графинюшка была у обедни у Разумовских, молитву новую слышала. Очень хорошая, говорит.
– Достал, – отвечал Пьер. – Завтра государь будет… Необычайное дворянское собрание и, говорят, по десяти с тысячи набор. Да, поздравляю вас.
– Да, да, слава богу. Ну, а из армии что?
– Наши опять отступили. Под Смоленском уже, говорят, – отвечал Пьер.
– Боже мой, боже мой! – сказал граф. – Где же манифест?
– Воззвание! Ах, да! – Пьер стал в карманах искать бумаг и не мог найти их. Продолжая охлопывать карманы, он поцеловал руку у вошедшей графини и беспокойно оглядывался, очевидно, ожидая Наташу, которая не пела больше, но и не приходила в гостиную.
– Ей богу, не знаю, куда я его дел, – сказал он.
– Ну уж, вечно растеряет все, – сказала графиня. Наташа вошла с размягченным, взволнованным лицом и села, молча глядя на Пьера. Как только она вошла в комнату, лицо Пьера, до этого пасмурное, просияло, и он, продолжая отыскивать бумаги, несколько раз взглядывал на нее.
– Ей богу, я съезжу, я дома забыл. Непременно…
– Ну, к обеду опоздаете.
– Ах, и кучер уехал.
Но Соня, пошедшая в переднюю искать бумаги, нашла их в шляпе Пьера, куда он их старательно заложил за подкладку. Пьер было хотел читать.
– Нет, после обеда, – сказал старый граф, видимо, в этом чтении предвидевший большое удовольствие.
За обедом, за которым пили шампанское за здоровье нового Георгиевского кавалера, Шиншин рассказывал городские новости о болезни старой грузинской княгини, о том, что Метивье исчез из Москвы, и о том, что к Растопчину привели какого то немца и объявили ему, что это шампиньон (так рассказывал сам граф Растопчин), и как граф Растопчин велел шампиньона отпустить, сказав народу, что это не шампиньон, а просто старый гриб немец.
– Хватают, хватают, – сказал граф, – я графине и то говорю, чтобы поменьше говорила по французски. Теперь не время.
– А слышали? – сказал Шиншин. – Князь Голицын русского учителя взял, по русски учится – il commence a devenir dangereux de parler francais dans les rues. [становится опасным говорить по французски на улицах.]
– Ну что ж, граф Петр Кирилыч, как ополченье то собирать будут, и вам придется на коня? – сказал старый граф, обращаясь к Пьеру.
Пьер был молчалив и задумчив во все время этого обеда. Он, как бы не понимая, посмотрел на графа при этом обращении.
– Да, да, на войну, – сказал он, – нет! Какой я воин! А впрочем, все так странно, так странно! Да я и сам не понимаю. Я не знаю, я так далек от военных вкусов, но в теперешние времена никто за себя отвечать не может.
После обеда граф уселся покойно в кресло и с серьезным лицом попросил Соню, славившуюся мастерством чтения, читать.
– «Первопрестольной столице нашей Москве.
Неприятель вошел с великими силами в пределы России. Он идет разорять любезное наше отечество», – старательно читала Соня своим тоненьким голоском. Граф, закрыв глаза, слушал, порывисто вздыхая в некоторых местах.
Наташа сидела вытянувшись, испытующе и прямо глядя то на отца, то на Пьера.
Пьер чувствовал на себе ее взгляд и старался не оглядываться. Графиня неодобрительно и сердито покачивала головой против каждого торжественного выражения манифеста. Она во всех этих словах видела только то, что опасности, угрожающие ее сыну, еще не скоро прекратятся. Шиншин, сложив рот в насмешливую улыбку, очевидно приготовился насмехаться над тем, что первое представится для насмешки: над чтением Сони, над тем, что скажет граф, даже над самым воззванием, ежели не представится лучше предлога.
Прочтя об опасностях, угрожающих России, о надеждах, возлагаемых государем на Москву, и в особенности на знаменитое дворянство, Соня с дрожанием голоса, происходившим преимущественно от внимания, с которым ее слушали, прочла последние слова: «Мы не умедлим сами стать посреди народа своего в сей столице и в других государства нашего местах для совещания и руководствования всеми нашими ополчениями, как ныне преграждающими пути врагу, так и вновь устроенными на поражение оного, везде, где только появится. Да обратится погибель, в которую он мнит низринуть нас, на главу его, и освобожденная от рабства Европа да возвеличит имя России!»
– Вот это так! – вскрикнул граф, открывая мокрые глаза и несколько раз прерываясь от сопенья, как будто к носу ему подносили склянку с крепкой уксусной солью. – Только скажи государь, мы всем пожертвуем и ничего не пожалеем.
Шиншин еще не успел сказать приготовленную им шутку на патриотизм графа, как Наташа вскочила с своего места и подбежала к отцу.
– Что за прелесть, этот папа! – проговорила она, целуя его, и она опять взглянула на Пьера с тем бессознательным кокетством, которое вернулось к ней вместе с ее оживлением.
– Вот так патриотка! – сказал Шиншин.
– Совсем не патриотка, а просто… – обиженно отвечала Наташа. – Вам все смешно, а это совсем не шутка…
– Какие шутки! – повторил граф. – Только скажи он слово, мы все пойдем… Мы не немцы какие нибудь…
– А заметили вы, – сказал Пьер, – что сказало: «для совещания».
– Ну уж там для чего бы ни было…
В это время Петя, на которого никто не обращал внимания, подошел к отцу и, весь красный, ломающимся, то грубым, то тонким голосом, сказал:
– Ну теперь, папенька, я решительно скажу – и маменька тоже, как хотите, – я решительно скажу, что вы пустите меня в военную службу, потому что я не могу… вот и всё…
Графиня с ужасом подняла глаза к небу, всплеснула руками и сердито обратилась к мужу.
– Вот и договорился! – сказала она.
Но граф в ту же минуту оправился от волнения.
– Ну, ну, – сказал он. – Вот воин еще! Глупости то оставь: учиться надо.
– Это не глупости, папенька. Оболенский Федя моложе меня и тоже идет, а главное, все равно я не могу ничему учиться теперь, когда… – Петя остановился, покраснел до поту и проговорил таки: – когда отечество в опасности.
– Полно, полно, глупости…
– Да ведь вы сами сказали, что всем пожертвуем.
– Петя, я тебе говорю, замолчи, – крикнул граф, оглядываясь на жену, которая, побледнев, смотрела остановившимися глазами на меньшого сына.
– А я вам говорю. Вот и Петр Кириллович скажет…
– Я тебе говорю – вздор, еще молоко не обсохло, а в военную службу хочет! Ну, ну, я тебе говорю, – и граф, взяв с собой бумаги, вероятно, чтобы еще раз прочесть в кабинете перед отдыхом, пошел из комнаты.
– Петр Кириллович, что ж, пойдем покурить…
Пьер находился в смущении и нерешительности. Непривычно блестящие и оживленные глаза Наташи беспрестанно, больше чем ласково обращавшиеся на него, привели его в это состояние.
– Нет, я, кажется, домой поеду…
– Как домой, да вы вечер у нас хотели… И то редко стали бывать. А эта моя… – сказал добродушно граф, указывая на Наташу, – только при вас и весела…
– Да, я забыл… Мне непременно надо домой… Дела… – поспешно сказал Пьер.
– Ну так до свидания, – сказал граф, совсем уходя из комнаты.
– Отчего вы уезжаете? Отчего вы расстроены? Отчего?.. – спросила Пьера Наташа, вызывающе глядя ему в глаза.
«Оттого, что я тебя люблю! – хотел он сказать, но он не сказал этого, до слез покраснел и опустил глаза.
– Оттого, что мне лучше реже бывать у вас… Оттого… нет, просто у меня дела.
– Отчего? нет, скажите, – решительно начала было Наташа и вдруг замолчала. Они оба испуганно и смущенно смотрели друг на друга. Он попытался усмехнуться, но не мог: улыбка его выразила страдание, и он молча поцеловал ее руку и вышел.
Пьер решил сам с собою не бывать больше у Ростовых.


Петя, после полученного им решительного отказа, ушел в свою комнату и там, запершись от всех, горько плакал. Все сделали, как будто ничего не заметили, когда он к чаю пришел молчаливый и мрачный, с заплаканными глазами.
На другой день приехал государь. Несколько человек дворовых Ростовых отпросились пойти поглядеть царя. В это утро Петя долго одевался, причесывался и устроивал воротнички так, как у больших. Он хмурился перед зеркалом, делал жесты, пожимал плечами и, наконец, никому не сказавши, надел фуражку и вышел из дома с заднего крыльца, стараясь не быть замеченным. Петя решился идти прямо к тому месту, где был государь, и прямо объяснить какому нибудь камергеру (Пете казалось, что государя всегда окружают камергеры), что он, граф Ростов, несмотря на свою молодость, желает служить отечеству, что молодость не может быть препятствием для преданности и что он готов… Петя, в то время как он собирался, приготовил много прекрасных слов, которые он скажет камергеру.
Петя рассчитывал на успех своего представления государю именно потому, что он ребенок (Петя думал даже, как все удивятся его молодости), а вместе с тем в устройстве своих воротничков, в прическе и в степенной медлительной походке он хотел представить из себя старого человека. Но чем дальше он шел, чем больше он развлекался все прибывающим и прибывающим у Кремля народом, тем больше он забывал соблюдение степенности и медлительности, свойственных взрослым людям. Подходя к Кремлю, он уже стал заботиться о том, чтобы его не затолкали, и решительно, с угрожающим видом выставил по бокам локти. Но в Троицких воротах, несмотря на всю его решительность, люди, которые, вероятно, не знали, с какой патриотической целью он шел в Кремль, так прижали его к стене, что он должен был покориться и остановиться, пока в ворота с гудящим под сводами звуком проезжали экипажи. Около Пети стояла баба с лакеем, два купца и отставной солдат. Постояв несколько времени в воротах, Петя, не дождавшись того, чтобы все экипажи проехали, прежде других хотел тронуться дальше и начал решительно работать локтями; но баба, стоявшая против него, на которую он первую направил свои локти, сердито крикнула на него:
– Что, барчук, толкаешься, видишь – все стоят. Что ж лезть то!
– Так и все полезут, – сказал лакей и, тоже начав работать локтями, затискал Петю в вонючий угол ворот.
Петя отер руками пот, покрывавший его лицо, и поправил размочившиеся от пота воротнички, которые он так хорошо, как у больших, устроил дома.
Петя чувствовал, что он имеет непрезентабельный вид, и боялся, что ежели таким он представится камергерам, то его не допустят до государя. Но оправиться и перейти в другое место не было никакой возможности от тесноты. Один из проезжавших генералов был знакомый Ростовых. Петя хотел просить его помощи, но счел, что это было бы противно мужеству. Когда все экипажи проехали, толпа хлынула и вынесла и Петю на площадь, которая была вся занята народом. Не только по площади, но на откосах, на крышах, везде был народ. Только что Петя очутился на площади, он явственно услыхал наполнявшие весь Кремль звуки колоколов и радостного народного говора.
Одно время на площади было просторнее, но вдруг все головы открылись, все бросилось еще куда то вперед. Петю сдавили так, что он не мог дышать, и все закричало: «Ура! урра! ура!Петя поднимался на цыпочки, толкался, щипался, но ничего не мог видеть, кроме народа вокруг себя.
На всех лицах было одно общее выражение умиления и восторга. Одна купчиха, стоявшая подле Пети, рыдала, и слезы текли у нее из глаз.
– Отец, ангел, батюшка! – приговаривала она, отирая пальцем слезы.
– Ура! – кричали со всех сторон. С минуту толпа простояла на одном месте; но потом опять бросилась вперед.
Петя, сам себя не помня, стиснув зубы и зверски выкатив глаза, бросился вперед, работая локтями и крича «ура!», как будто он готов был и себя и всех убить в эту минуту, но с боков его лезли точно такие же зверские лица с такими же криками «ура!».
«Так вот что такое государь! – думал Петя. – Нет, нельзя мне самому подать ему прошение, это слишком смело!Несмотря на то, он все так же отчаянно пробивался вперед, и из за спин передних ему мелькнуло пустое пространство с устланным красным сукном ходом; но в это время толпа заколебалась назад (спереди полицейские отталкивали надвинувшихся слишком близко к шествию; государь проходил из дворца в Успенский собор), и Петя неожиданно получил в бок такой удар по ребрам и так был придавлен, что вдруг в глазах его все помутилось и он потерял сознание. Когда он пришел в себя, какое то духовное лицо, с пучком седевших волос назади, в потертой синей рясе, вероятно, дьячок, одной рукой держал его под мышку, другой охранял от напиравшей толпы.
– Барчонка задавили! – говорил дьячок. – Что ж так!.. легче… задавили, задавили!
Государь прошел в Успенский собор. Толпа опять разровнялась, и дьячок вывел Петю, бледного и не дышащего, к царь пушке. Несколько лиц пожалели Петю, и вдруг вся толпа обратилась к нему, и уже вокруг него произошла давка. Те, которые стояли ближе, услуживали ему, расстегивали его сюртучок, усаживали на возвышение пушки и укоряли кого то, – тех, кто раздавил его.
– Этак до смерти раздавить можно. Что же это! Душегубство делать! Вишь, сердечный, как скатерть белый стал, – говорили голоса.
Петя скоро опомнился, краска вернулась ему в лицо, боль прошла, и за эту временную неприятность он получил место на пушке, с которой он надеялся увидать долженствующего пройти назад государя. Петя уже не думал теперь о подаче прошения. Уже только ему бы увидать его – и то он бы считал себя счастливым!
Во время службы в Успенском соборе – соединенного молебствия по случаю приезда государя и благодарственной молитвы за заключение мира с турками – толпа пораспространилась; появились покрикивающие продавцы квасу, пряников, мака, до которого был особенно охотник Петя, и послышались обыкновенные разговоры. Одна купчиха показывала свою разорванную шаль и сообщала, как дорого она была куплена; другая говорила, что нынче все шелковые материи дороги стали. Дьячок, спаситель Пети, разговаривал с чиновником о том, кто и кто служит нынче с преосвященным. Дьячок несколько раз повторял слово соборне, которого не понимал Петя. Два молодые мещанина шутили с дворовыми девушками, грызущими орехи. Все эти разговоры, в особенности шуточки с девушками, для Пети в его возрасте имевшие особенную привлекательность, все эти разговоры теперь не занимали Петю; ou сидел на своем возвышении пушки, все так же волнуясь при мысли о государе и о своей любви к нему. Совпадение чувства боли и страха, когда его сдавили, с чувством восторга еще более усилило в нем сознание важности этой минуты.
Вдруг с набережной послышались пушечные выстрелы (это стреляли в ознаменование мира с турками), и толпа стремительно бросилась к набережной – смотреть, как стреляют. Петя тоже хотел бежать туда, но дьячок, взявший под свое покровительство барчонка, не пустил его. Еще продолжались выстрелы, когда из Успенского собора выбежали офицеры, генералы, камергеры, потом уже не так поспешно вышли еще другие, опять снялись шапки с голов, и те, которые убежали смотреть пушки, бежали назад. Наконец вышли еще четверо мужчин в мундирах и лентах из дверей собора. «Ура! Ура! – опять закричала толпа.
– Который? Который? – плачущим голосом спрашивал вокруг себя Петя, но никто не отвечал ему; все были слишком увлечены, и Петя, выбрав одного из этих четырех лиц, которого он из за слез, выступивших ему от радости на глаза, не мог ясно разглядеть, сосредоточил на него весь свой восторг, хотя это был не государь, закричал «ура!неистовым голосом и решил, что завтра же, чего бы это ему ни стоило, он будет военным.
Толпа побежала за государем, проводила его до дворца и стала расходиться. Было уже поздно, и Петя ничего не ел, и пот лил с него градом; но он не уходил домой и вместе с уменьшившейся, но еще довольно большой толпой стоял перед дворцом, во время обеда государя, глядя в окна дворца, ожидая еще чего то и завидуя одинаково и сановникам, подъезжавшим к крыльцу – к обеду государя, и камер лакеям, служившим за столом и мелькавшим в окнах.
За обедом государя Валуев сказал, оглянувшись в окно:
– Народ все еще надеется увидать ваше величество.
Обед уже кончился, государь встал и, доедая бисквит, вышел на балкон. Народ, с Петей в середине, бросился к балкону.
– Ангел, отец! Ура, батюшка!.. – кричали народ и Петя, и опять бабы и некоторые мужчины послабее, в том числе и Петя, заплакали от счастия. Довольно большой обломок бисквита, который держал в руке государь, отломившись, упал на перилы балкона, с перил на землю. Ближе всех стоявший кучер в поддевке бросился к этому кусочку бисквита и схватил его. Некоторые из толпы бросились к кучеру. Заметив это, государь велел подать себе тарелку бисквитов и стал кидать бисквиты с балкона. Глаза Пети налились кровью, опасность быть задавленным еще более возбуждала его, он бросился на бисквиты. Он не знал зачем, но нужно было взять один бисквит из рук царя, и нужно было не поддаться. Он бросился и сбил с ног старушку, ловившую бисквит. Но старушка не считала себя побежденною, хотя и лежала на земле (старушка ловила бисквиты и не попадала руками). Петя коленкой отбил ее руку, схватил бисквит и, как будто боясь опоздать, опять закричал «ура!», уже охриплым голосом.
Государь ушел, и после этого большая часть народа стала расходиться.
– Вот я говорил, что еще подождать – так и вышло, – с разных сторон радостно говорили в народе.
Как ни счастлив был Петя, но ему все таки грустно было идти домой и знать, что все наслаждение этого дня кончилось. Из Кремля Петя пошел не домой, а к своему товарищу Оболенскому, которому было пятнадцать лет и который тоже поступал в полк. Вернувшись домой, он решительно и твердо объявил, что ежели его не пустят, то он убежит. И на другой день, хотя и не совсем еще сдавшись, но граф Илья Андреич поехал узнавать, как бы пристроить Петю куда нибудь побезопаснее.