Сигнал C SIGINT в Linux

Сигнал C SIGINT в Linux

Я хочу создать определенную комбинацию клавиш клавиатуры для завершения процесса, например, я хочу завершить процесс нажатием CTRL + C ^ 3 (троекратное нажатие C: CTRL + CCC).

По сути, я хочу заменить CTRL + C на CTRL + CCC.

решение1

Поведение по умолчанию Ctrl+ Cпредставляет собой комбинацию двух вещей. Драйвер терминала¹ не передает это нажатие клавиши, а вместо этого отправляетСигнал SIGINTк процессу переднего плана². По умолчанию процесс завершается, когда он получает SIGINT, но процесс может установить обработчик сигнала, а затем он запустит обработчик сигнала, когда получит SIGINT.

Невозможно настроить драйвер терминала так, чтобы он преобразовывал только третий Ctrl+ Cв строке для завершения процесса переднего плана. Чтобы сделать это, вам нужно сосчитать до трех в вашей программе. Есть два способа сделать это, которые будут вести себя по-разному, если пользователь нажмет что-то еще между Ctrl+ C.

Один из способов — отключить поведение Ctrl+ Cпо отправке сигнала и сообщить драйверу терминала, что вместо этого нужно передать его. Это можно сделать, вызвавstty intr \^-из скрипта оболочки илиtcsetattr(fd, &termios)с termios.c_cc[VINTR]установленным значением _POSIX_VDISABLEиз C. Затем в цикле обработки ввода вашей программы выйдите, когда увидите три символа Ctrl+ Cподряд.

Другой способ — установить обработчик сигнала для SIGINT, который подсчитывает, сколько раз он был вызван, и завершает программу на третий раз. Вы можете захотеть сбросить счетчик, если между ними есть нормальный ввод.

¹ Не эмулятор терминала, а общая часть операционной системы, которая обрабатывает все терминалы.
² Я только объясняю простой случай. Это не трактат о том, как работает драйвер терминала.

решение2

Вы не можете изменить привязку клавиш в своем коде, поскольку сигнал — это программное прерывание, которое ОС отправляет процессу. Когда пользователь нажимает ctrl-c, другой процесс что-то сообщает вашему процессу.

Есть фиксированный набор сигналов, которые могут быть отправлены процессу. Сигналы похожи на прерывания, разница в том, что прерывания опосредуются процессором и обрабатываются ядром, тогда как сигналы опосредуются ядром (возможно, через системные вызовы) и обрабатываются процессами. Ядро может передать прерывание как сигнал процессу, который его вызвал (типичные примеры — SIGSEGV, SIGBUS, SIGILL и SIGFPE).

Вы можете переназначить привязку клавиш сигнала на своем компьютере с помощью stty

Включите Ctrl+C для копирования и Ctrl+Shift+C для прерывания

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

если вы хотите ровно 3 нажатия ctrl-c, вы можете посчитать SIGINT и прервать программу при 3 нажатиях ctrl-c. (нажатие трех раз 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;
}

Связанный контент