プロセスを終了するために、特定のキーボード キーの組み合わせを作成したいです。たとえば、CTRL + C ^ 3 (C を 3 回押す: CTRL +CCC) を押してプロセスを終了したいです。
つまり、CTRL + CをCTRL + CCCに置き換えたいのです
答え1
Ctrl+のデフォルトの動作はC2つの要素を組み合わせたものです。端末ドライバ¹は、このキーの押下を送信せず、代わりにSIGINT信号フォアグラウンド プロセス² に。デフォルトでは、プロセスは SIGINT を受信すると終了しますが、プロセスはシグナル ハンドラーを設定することができ、SIGINT を受信するとシグナル ハンドラーを実行します。
Ctrl連続する 3 番目の+のみを変換してフォアグラウンド プロセスを強制終了するようにターミナル ドライバーを構成する方法はありませんC。これを行うには、プログラムで 3 まで数える必要があります。これを行うには 2 つの方法があり、ユーザーがCtrl+Cの間に何か他のものを押した場合、動作が異なります。
一つの方法は、Ctrl+Cのシグナル送信の動作を無効にして、代わりにターミナルドライバにシグナルを通過させるように指示することです。これを行うには、stty intr \^-
シェルスクリプトからまたはtcsetattr(fd, &termios)
C からをtermios.c_cc[VINTR]
設定します_POSIX_VDISABLE
。次に、プログラムの入力処理ループで、Ctrl+Cが 3 つ連続したら終了します。
もう 1 つの方法は、SIGINT のシグナル ハンドラーを設定し、呼び出された回数をカウントして 3 回目にプログラムを終了することです。その間に通常の入力があった場合は、カウンターをリセットすることをお勧めします。
¹端末エミュレーターではありません。これは、すべての端末を処理するオペレーティング システムの汎用部分です。²
ここでは単純なケースについてのみ説明しています。これは、端末ドライバーの動作に関する論文ではありません。
答え2
シグナルは、OS によってプロセスに送信されるソフトウェア生成の割り込みであるため、コード内でキー バインディングを変更することはできません。ユーザーが 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 を 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;
}