Sinal C SIGINT no Linux

Sinal C SIGINT no Linux

Quero fazer uma combinação específica de teclas do teclado para encerrar um processo, ex. Quero encerrar o processo pressionando CTRL + C ^ 3 (pressionando três vezes C: CTRL + CCC).

Então, basicamente, quero substituir CTRL + C por CTRL + CCC

Responder1

O comportamento padrão de Ctrl+ Cé uma combinação de duas coisas. O driver do terminal¹ não transmite esse pressionamento de tecla, mas em vez disso envia umSinal SIGINTpara o processo em primeiro plano². Por padrão, um processo morre quando recebe um SIGINT, mas o processo pode definir um manipulador de sinal e então executará o manipulador de sinal quando receber SIGINT.

Não há como configurar o driver do terminal para converter apenas o terceiro Ctrl+ Cconsecutivo para encerrar o processo em primeiro plano. Para fazer isso, você precisa contar até três em seu programa. Existem duas maneiras de fazer isso, que se comportarão de maneira diferente se o usuário pressionar outra coisa entre os Ctrl+ C.

Uma maneira é desabilitar o comportamento de Ctrl+ Cde enviar um sinal e dizer ao driver do terminal para passá-lo. Você pode fazer isso ligandostty intr \^-de um script de shell outcsetattr(fd, &termios)with termios.c_cc[VINTR]definido _POSIX_VDISABLEcomo C. Então, no loop de processamento de entrada do seu programa, saia quando você tiver visto três Ctrl+ C's seguidos.

A outra maneira é definir um manipulador de sinal para SIGINT que conte quantas vezes ele foi invocado e finalize o programa pela terceira vez. Você pode querer zerar o contador se houver uma entrada normal entre eles.

¹ Não é o emulador de terminal, a parte genérica do sistema operacional que lida com todos os terminais.
² Estou apenas explicando o caso simples. Este não é um tratado sobre como funciona o driver do terminal.

Responder2

Você não pode alterar a ligação de teclas em seu código porque um sinal é uma interrupção gerada por software que é enviada a um processo pelo sistema operacional. quando o usuário pressiona ctrl-c, outro processo informa algo ao seu processo.

Existem conjuntos fixos de sinais que podem ser enviados para um processo. os sinais são semelhantes às interrupções, a diferença é que as interrupções são mediadas pelo processador e tratadas pelo kernel, enquanto os sinais são mediados pelo kernel (possivelmente por meio de chamadas do sistema) e tratados pelos processos. O kernel pode passar uma interrupção como um sinal para o processo que a causou (exemplos típicos são SIGSEGV, SIGBUS, SIGILL e SIGFPE).

você pode remapear a ligação de teclas de sinal em seu computador com stty

Habilite Ctrl+C para cópia e Ctrl+Shift+C para interrput

https://docstore.mik.ua/orelly/unix3/upt/ch05_08.htm

se você quiser exatamente 3 vezes ctrl-c. você pode contar SIGINT e interromper o programa quando ctrl-c for pressionado 3 vezes. (pressionando três vezes C: CTRL +CCC).

#include<stdio.h>
#include<signal.h>
#include<unistd.h>

void sig_handler(int signo)
{
    static int counter=0;
    if (signo == SIGINT)
        counter++;
    printf("received SIGINT %d times\n", counter);
    if (counter == 3)
        exit(0);
}

int main() 
{ 
    if (signal(SIGINT, sig_handler) == SIG_ERR)
        printf("\ncan't catch SIGINT\n");
    while(1) 
        sleep(1);
    return 0;
}

informação relacionada