![]() |
|
Модераторы: xvr |
![]()
|
|
| savigm |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 15.12.2008 Где: г. Зеленоград Репутация: нет Всего: нет |
Добрый день.
Есть скрипт на bash запускающий программу, не соодержащую обработчика сигналов. По запуску скрипта, во время выполнения программы, если нажать [CTRL]+[C] - на экран вылезет ^C. Одно из двух - либо bash отображает введенный символ, либо ядро обрабатывая сигнал и выдает на терминал ^C. Поясните поподробней от кого идет выдача и как этого избажать(перенаправление вввода-вывода не помогает). |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
я так понимаю речь идет про GUI эмулятор терминала типа gnome-terminal и Konsole
обычно с GUI эмуляторами терминалов связываются программы-интерпретаторы (bash, csh, zsh и т. д) говоря простым языком это то, что мы прописываем в конфиге (или в другом месте) GUI программы и что запускается при ее старте если углубиться в детали, то происходит следующее 1. при запуске GUI эмулятора он через open() открывает /dev/ptmx реализация обработчика open для /dev/ptmx создает псевдотерминальное устройство, состоящее из master и slave компонентов доступ к master компоненту имеет только процесс GUI эмулятора (open() возвращает ему соответствующий дескриптор) slave компонент доступен любому процессу через виртуальную ФС /dev/pts (в процессе работы обработчика open slave компонент отображается на /dev/pts в виде файла символьного устройства 0, 1, 2, ..., который можно открыть) 2. GUI эмулятор порождает процесс и запускает в нем соответствующий ему интерпретатор через execve() перед вызовом execve() он перенаправляет стандартный ввод-вывод порожденного процесса на /dev/pts/X, где X - символьное устройство, соответствующее slave компоненту псевдотерминального устройства все, связь готова 3. GUI эмулятор связан через gtk[+]/qt с Xlib API, через который он взаимодействует с X сервером и в частности получает события от клавиатуры при наборе текста (это могут быть скан-коды или что-то другое) на этом уровне различные комбинации типа ^C представляют собой просто последовательность байт 4. вся последовательность байт as is записывается в master компонент через write() на дескрипторе вот тут начинаетс шаманство ;) из буфера master компонента последовательность байт передается в slave компонент, где идет ее преобразование в соответствие с настройками slave компонента настроить можно через ioctl или tc* обертки на дескрипторе, полученном через open() на /dev/pts/X здесь как раз можно связать управляющую комбинацию ^C и генерацию сигнала т. е slave компонент при парсинге последовательности байт может сгенерировать сигнал для всех процессов из foreground группы, которые используют /dev/pts/X в виде дескриптора bash всегда перехватывает SIGINT (маппинг ^C) и записывает символьную последовательность "^C" на стандартный поток вывода, который, как я отмечал выше, связан со slave компонентом. Эта последовательность байт без изменений копируется в приемный буфер master компонента дальше GUI эмулятор может прочесть эти данные через read() на своем дескрипторе и вывести их через Xlib API на экран -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| savigm |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 15.12.2008 Где: г. Зеленоград Репутация: нет Всего: нет |
Ok, тогда как обьяснить аналогичное явление в виртуальной консоли (не терминале):
в login (это еще не bash) нажатие [Ctrl]+[C] также приводит к отображению ^C? Во время работы программы ввод-вывод если я не ошибаюсь идет уже не с bash, а с программой. Как все-таки этого избежать? Есть прогамка с обработчиком сигнала SIGINT, так она нормально завершается ничего не отображая. Получается сей эффект проявляется только если в программе не установлен обработчик сигнала? Кроме того: если посылать kill -2 <PID>, никакого ^C нет. Т.е. это следствие нажатия клавиш, а не сигнала как такового, однако наличие обработчика решает проблему. Это сообщение отредактировал(а) savigm - 27.3.2009, 01:50 |
|||
|
||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
я же специально написал замени /dev/pts/X на /dev/ttyX и получишт тот же эффект для login Добавлено через 10 минут и 20 секунд посмотри опции stty -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| savigm |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 15.12.2008 Где: г. Зеленоград Репутация: нет Всего: нет |
Slave компонент насколько я понимаю связан с bash? Если в терминале у меня запущена программа весь ввод и вывод идет на нее по схеме Клавиатура/Монитор<->Терминал<->Bash<->Программа? Т.е. весь клавиатурный ввод серва парсится bash'ом, потом отправляется на /dev/ptsx? Что значит "для всех процессов из foreground группы", разве foreground - это не единственная программа запущенная в bash и занимающая ввод-вывод консоли/терминала? Интересный факт: в интерпретаторе bash если нажать [Ctrl]+[C], он перехватывает сигнал и на терминал выводится символ новой строки вместо ^C. Вот код из исходников bash - файл sig.c:
Вот еще интересный кусочек из исходников bash - файл jobs.c, правда относящийся к job control(в комментарии ясно написано что выводом ^C занимается обработчик ядра):
Это сообщение отредактировал(а) savigm - 27.3.2009, 13:12 |
||||
|
|||||
| MAKCim |
|
|||
![]() Воін дZэна ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5644 Регистрация: 10.12.2005 Где: Менск, РБ Репутация: 84 Всего: 207 |
bash лишний в цепочке и bash, и программа используют один и тот же /dev/pts/X а вообще меня самого заинтересовало как-нибудь на досуге разрулю этот вопрос -------------------- Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі © |
|||
|
||||
| savigm |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 88 Регистрация: 15.12.2008 Где: г. Зеленоград Репутация: нет Всего: нет |
stty -echoctl - действительно помогает, но я решил проблему иным путем: т.к. моя программа не использует ввод, то я просто отрубил ECHO в начале программы и включил в конце, но это все work around, суть вопроса по прежнему не ясна. Насколько я понимаю все дело в настройках терминала, т.е. по идее на терминале должно отобразится что-то типа ^[[ и т.п. а терминал преобразует это в ^C ^Q и т.п.
|
|||
|
||||
![]()
|
| Правила форума "С/С++: Программирование под Unix/Linux" | |
|
|
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |