O shell Bash lançado por forkpty () gera processos filhos que ignoram o SIGINT. Por que e como garantir que o SIGINT não seja ignorado?

3

Eu tenho um programa C que usa forkpty para executar um shell bash. Eu estou achando que os programas lançados por este shell são iniciados com o SIGINT ignorado, então quando eu envio um Ctrl-C para o shell eles nunca fecham.

exemplo:

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
}

Outros caracteres de controle parecem passar, ctrl-D, ctrl-? No entanto, sempre que eu olho para o status de um processo iniciado pelo novo shell bash, parece que o SIGINT está mascarado.

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

O SigIgn tem o conjunto de 2 bits, o que significa que 2 (SIGINT) é ignorado. se eu faço exatamente a mesma coisa, mas corro o sono (ou cato um arquivo gigante ou qualquer outro) em um terminal padrão, esse bit é apagado. O que estou fazendo quando lanço meu bash pty que está causando a criação de programas de netos com o SIGINT ignorados?

Além disso, se eu enviar um sinal SIGINT para o processo

StandardTerm:# kill -2 26611

nada acontece. O que é estranho é quando eu envio o mesmo comando para o shell bash que eu forkpty'ed funciona, porque esse shell bash não está ignorando o SIGINT.

    
por djc6535 09.11.2015 / 17:52

1 resposta

0

talvez você só precise fazer:

stty sane

Noto que a página forkpty() man diz que copiará as configurações de termios *termp para o pty recém-aberto, mas ele não diz especificamente o que faz com isso de outra forma, e o único argumento não-NULL que você entrega forkpty() é para o pty master fd. Eu acho que você acabaria com uma estrutura termios inteiramente NULL, que não pode ser muito útil. Ele não se incomodaria bash terrivelmente que tem readline() para lidar com todo o seu próprio material de terminal, e assim interpretaria todos os caracteres padrão por padrão.

a"qui está um blockquote de um a"rtigo a"> sobre o assunto:

stty's -F option can be great for peeking at what some other program is doing to its terminal. If you run tty in a shell, it will print the path to that shell's terminal device (usually of the form /dev/pts/N, at least under Linux). Now, from a different shell, you can run stty -a -F /dev/pts/N to see how the first shell's terminal is configured. You can then run programs in the first shell, and repeat the stty incant in shell two to see what settings are getting set. For example, if I run stty -F /dev/pts/10 right now (while I have a bash talking to a gnome-terminal via that pty), I see:

    $ 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

So we can see that bash/readline has disabled CR→LF translation on input (icrnl), disabled canonical mode and echo, but turned on UTF-8 mode (because bash detected a utf-8 locale). Note that if I run stty directly in that shell, I see something slightly different:

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

This is because bash maintains its own set of termios settings (for readline), and saves and restores settings around running programs, so that settings in place while running a program are different from those in place while you're typing at the bash prompt.

    
por 09.11.2015 / 21:57