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_VDISABLE
como 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;
}