Intereting Posts
Переместить в следующую заглавную букву Есть ли способ сказать, был ли сценарий оболочки убит сигналом 9 Как я могу предотвратить gunzip | ntfsclone для зависания, если источник zip не читается Скопируйте соответствующие строки текстового файла, содержащего строку, в другой файл Как вы перечисляете все функции и псевдонимы в определенном скрипте? Как настроить Request Tracker на Debian и создавать билеты? PfSense VPN L2TP бежит с клиентами Windows Исходный цикл чтения скрипта bash Как я могу проверить, запущен ли мой cronjob на моем сервере через PHP? facl игнорирует разрешение «x», но только на файлы Использовать sed для печати с первой строки до строки, содержащей последнее вхождение шаблона? virt-manager для копирования вставки vm Как отформатировать карту microSDXC в Fat32? Ядро делает ошибку: «извините, не реализовано: -mfloat-abi = hard и VFP» Как добавить принтер ricoh 2018d?

Баш-оболочка, запущенная forkpty (), порождает дочерние процессы, игнорирующие SIGINT. Почему и как я могу гарантировать, что SIGINT не игнорируется?

У меня есть программа на C, которая использует forkpty для выполнения оболочки bash. Я обнаружил, что программы, запущенные этой оболочкой, запускаются с игнорированием SIGINT, поэтому, когда я отправляю Ctrl-C в оболочку, они никогда не закрываются.

пример:

int masterFd; char* args[] = {"/bin/bash", "-i", NULL }; int procId = forkpty(&masterFd, NULL, NULL, NULL); if( procId == 0 ){ execve( args[0], args, NULL); } else { // Simple code that reads from standard in and writes to masterFd. // I also register for Ctrl-C and write it to masterFd if caught } 

Другие управляющие символы, похоже, пробиваются, ctrl-D, ctrl-? и т. д. Однако всякий раз, когда я смотрю на состояние процесса, запускаемого новой оболочкой bash, кажется, что SIGINT замаскирован.

 MyShell:# sleep 1000 StandardTerm:# ps -ef | grep sleep root 26611 19278 0 17:44 pts/1 00:00:00 sleep 1000 root 26613 32376 0 17:44 pts/1 00:00:00 grep sleep StandardTerm:# grep Sig proc/26611/status SigQ: 0/256428 SigPnd: 0000000000000000 SigBlk: 0000000000000000 SigIgn: 0000000000010006 <- THE 6 IS THE PROBLEM SigCgt: 0000000180000000 

SigIgn имеет 2-битный набор, что означает, что 2 (SIGINT) игнорируется. если я делаю то же самое, но запускаю сон (или кот – гигантский файл или что-то еще) в стандартном терминале, этот бит очищается. Что я делаю, когда запускаю свой pty bash, который заставляет его создавать программы внуков с игнорированием SIGINT?

Более того, если я отправлю сигнал SIGINT в процесс

 StandardTerm:# kill -2 26611 

Ничего не произошло. Что странно, когда я отправляю ту же команду в оболочку bash, я работаю forkpty'ed, потому что эта оболочка bash не игнорирует SIGINT.

возможно, вам просто нужно сделать:

 stty sane 

Я замечаю, что на forkpty() man forkpty() говорится, что она скопирует настройки termios *termp на вновь открытую pty, но в ней конкретно не говорится, что она делает с ними в противном случае, и единственный не-NULL arg you hand forkpty() для pty master fd. Я бы предположил, что вы закончите с полностью NULL termios структурой, что не может быть очень полезно. Он не стал бы беспокоить bash ужасно, у которого есть readline() чтобы обрабатывать все свои собственные материалы терминала, и поэтому он все равно будет интерпретировать все символы по умолчанию.

вот блок-лист из довольно содержательной статьи на эту тему:

stty 's -F могут отлично подглядывать за тем, что делает какая-то другая программа для своего терминала. Если вы запустите tty в оболочке, он напечатает путь к терминальному устройству этой оболочки (обычно формы /dev/pts/N , по крайней мере, под Linux) . Теперь из другой оболочки вы можете запустить stty -a -F /dev/pts/N чтобы увидеть, как настроен терминал первого корпуса. Затем вы можете запускать программы в первой оболочке и повторять stty incant во второй оболочке, чтобы узнать, какие настройки устанавливаются. Например, если я запускаю stty -F /dev/pts/10 прямо сейчас (пока у меня есть bash говорящий с gnome-terminal через этот pty) , я вижу:

  $ stty -F /dev/pts/10 speed 38400 baud; line = 0; eol = M-^?; eol2 = M-^?; swtch = M-^?; lnext = <undef>; min = 1; time = 0; -icrnl iutf8 -icanon -echo 

Таким образом, мы можем видеть, что bash/readline отключил CR→LF перевод на входе ( icrnl ) , отключил canonical режим и echo , но включил режим UTF-8 (потому что bash обнаружил локаль utf-8) . Обратите внимание, что если я запускаю stty непосредственно в этой оболочке, я вижу что-то немного другое:

  $ stty speed 38400 baud; line = 0; eol = M-^?; eol2 = M-^?; swtch = M-^?; iutf8 

Это связано с тем, что bash поддерживает собственный набор параметров termios (для readline ) и сохраняет и восстанавливает настройки вокруг запущенных программ, так что настройки во время работы программы отличаются от настроек, когда вы печатаете в bash строке bash .