LinuxのC SIGINT信号

LinuxのC SIGINT信号

プロセスを終了するために特定のキーボードキーの組み合わせを作成したいと思います。たとえば、CTRL+C^3(C を 3 回押す: CTRL+CCC) を押してプロセスを終了したいとします。

だから基本的にCTRL + CをCTRL + CCCに置き換えたいのです。

答え1

Ctrl+のデフォルトの動作Cは2つの組み合わせです。ターミナルドライバ1はこのキーストロークを送信しません。SIGINT信号フォアグラウンドプロセス²として。デフォルトでは、プロセスはSIGINTを受信すると終了しますが、プロセスはシグナルハンドラを設定し、SIGINTを受信するとシグナルハンドラを実行できます。

Ctrl3番目の連続+のみ変換してCフォアグラウンドプロセスを終了するようにターミナルドライバを設定することはできません。これを行うには、プログラムで3まで数える必要があります。これを行う方法は2つあります。ユーザーがCtrl+間の他の項目を押すと、動作が異なりますC

Ctrl1つのアプローチは、+ SendSignalを無効にCし、ターミナルドライバに信号伝達の動作を知らせることです。電話してくださいstty intr \^-シェルスクリプトで、またはtcsetattr(fd, &termios)その後、プログラムの入力処理ループでtermios.c_cc[VINTR]3つの+が連続して表示されたら終了します。_POSIX_VDISABLECtrlC

もう1つのアプローチは、SIGINTのシグナルハンドラを設定し、呼び出し回数を数えて3番目にプログラムを終了することです。その間に通常の入力がある場合、カウンタをリセットする必要があるかもしれません。

1は端末エミュレータではなく、すべての端末を処理するオペレーティングシステムの一般的な部分です。
²簡単な状況を説明しています。これは、端末ドライバの動作方法に関する論文ではありません。

答え2

シグナルはオペレーティングシステムからプロセスに送信されるソフトウェア生成割り込みであるため、コードのキーバインディングを変更することはできません。ユーザーが ctrl-c を押すと、他のプロセスがプロセスにいくつかの情報を通知します。

プロセスに送信できる一連の固定信号があります。信号は割り込みに似ていますが、割り込みはプロセッサによって調整され、カーネルによって処理されますが、信号はカーネルによって調整され(おそらくシステムコールを介して)プロセスによって処理されます。カーネルは、割り込みを発生したプロセスに信号として割り込みを渡すことができます(一般的な例はSIGSEGV、SIGBUS、SIGILL、およびSIGFPE)。

sttyを使用して、コンピュータの信号キーバインディングを再マップできます。

コピーするにはCtrl + Cを、挿入するにはCtrl + Shift + Cを有効にします。

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

ctrl-cを正確に3回したい場合。 ctrl-cを3回押すと、SIGINTを評価してプログラムを中断できます。 (Cを3回押す: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;
}

関連情報