C SIGINT-Signal in Linux

C SIGINT-Signal in Linux

Ich möchte eine bestimmte Tastenkombination eingeben, um einen Prozess zu beenden. Beispiel: Ich möchte den Prozess durch Drücken von STRG + C ^ 3 beenden (dreimaliges Drücken von C: STRG + CCC).

Im Grunde möchte ich STRG + C durch STRG + CCC ersetzen

Antwort1

Das Standardverhalten von Ctrl+ Cist eine Kombination aus zwei Dingen. Der Terminaltreiber¹ überträgt diesen Tastendruck nicht, sondern sendet stattdessen eineSIGINT-Signalzum Vordergrundprozess². Standardmäßig wird ein Prozess beendet, wenn er ein SIGINT empfängt, aber der Prozess kann einen Signalhandler festlegen und diesen dann ausführen, wenn er ein SIGINT empfängt.

Es gibt keine Möglichkeit, den Terminaltreiber so zu konfigurieren, dass nur das dritte Ctrl+ Cin einer Reihe konvertiert wird, um den Vordergrundprozess zu beenden. Dazu müssen Sie in Ihrem Programm bis drei zählen. Dies können Sie auf zwei Arten tun, die sich unterschiedlich verhalten, wenn der Benutzer zwischen den Ctrl+ etwas anderes drückt C.

CtrlEine Möglichkeit besteht darin, das Verhalten von + beim Senden eines Signals zu deaktivieren Cund den Terminaltreiber anzuweisen, es stattdessen durchzuleiten. Sie können dies tun, indem Siestty intr \^-aus einem Shell-Skript odertcsetattr(fd, &termios)mit termios.c_cc[VINTR]„set to“ _POSIX_VDISABLEvon C. Beenden Sie dann die Eingabeverarbeitungsschleife Ihres Programms, wenn Sie drei Ctrl+ Chintereinander gesehen haben.

Die andere Möglichkeit besteht darin, einen Signalhandler für SIGINT einzurichten, der zählt, wie oft es aufgerufen wurde, und das Programm beim dritten Mal beendet. Möglicherweise möchten Sie den Zähler zurücksetzen, wenn zwischendurch eine normale Eingabe erfolgt.

¹ Nicht der Terminalemulator, der generische Teil des Betriebssystems, der alle Terminals verwaltet.
² Ich erkläre nur den einfachen Fall. Dies ist keine Abhandlung über die Funktionsweise des Terminaltreibers.

Antwort2

Sie können die Tastenbelegung in Ihrem Code nicht ändern, da ein Signal ein softwaregenerierter Interrupt ist, der vom Betriebssystem an einen Prozess gesendet wird. Wenn der Benutzer Strg-C drückt, teilt ein anderer Prozess Ihrem Prozess etwas mit.

Es gibt einen festen Satz von Signalen, die an einen Prozess gesendet werden können. Signale ähneln Interrupts, der Unterschied besteht darin, dass Interrupts vom Prozessor vermittelt und vom Kernel verarbeitet werden, während Signale vom Kernel (möglicherweise über Systemaufrufe) vermittelt und von Prozessen verarbeitet werden. Der Kernel kann einen Interrupt als Signal an den Prozess weiterleiten, der ihn verursacht hat (typische Beispiele sind SIGSEGV, SIGBUS, SIGILL und SIGFPE).

Sie können die Signaltastenbelegung auf Ihrem Computer mit stty neu zuordnen.

Aktivieren Sie Strg+C zum Kopieren und Strg+Umschalt+C zum Eingeben

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

Wenn Sie also genau dreimal Strg-C drücken möchten, können Sie SIGINT zählen und das Programm unterbrechen, wenn Sie dreimal Strg-C drücken. (dreimal C drücken: STRG + 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;
}

verwandte Informationen