最小限のテキストエディターであるプログラムed
は、使用して割り込みを送信しても終了できません Ctrl-C、代わりにエラーメッセージ「?」を出力しますコンソールに。なぜ割り込みを受け取ったときにed
が終了しないのですか?確かに、ここに存在するだけでなく、不可解なエラーメッセージの方が役立つ理由はありません。この動作により、多くの新規ユーザーは次のようなやり取りにつながります。
$ ed hello ? help ? exit ? quit ? ^C ? ^C ? ? ? ^D $ su # rm -f /bin/ed
そのような悲劇的な無駄— ed
が単に中断されることに同意した場合、簡単に回避できます。
同様の動作を示す別の頑固なプログラムはless
でもあり、これも無視する理由があまりないようですC-c
。なぜこれらのプログラムは単にヒントをとらないのですか?
Ctrl+C 送信 [〜#〜] sigint [〜#〜] 。 SIGINTの従来のアクションは、プログラムの最上位ループに戻り、現在のコマンドをキャンセルして、プログラムが次のコマンドを待つモードに入ります。非対話型プログラムのみがSIGINTで終了することになっています。
だから当然です Ctrl+C edを強制終了しませんが、最上位のループに戻ります。 Ctrl+C 現在の入力行を中止し、edプロンプトに戻ります。
同じことがより少なくなります: Ctrl+C 現在のコマンドを中断し、コマンドプロンプトに戻ります。
歴史的な理由により、edは [〜#〜] sigquit [〜#〜] (Ctrl+\)。通常のアプリケーションはこの信号をキャッチせず、有効になっている場合はコアダンプを使用して自身を終了させる必要があります。
nix V7 ed(1)
ソースコード は、少数のコメントのみを含むプリミティブな1,762行のCプログラムであり、そのうちの1つはこの非常にわかりやすいヘッダーコメントです。
_/*
* Editor
*/
_
ソースコード自体には根拠がないため、プログラムの作成者から入手するだけです。
ed
は元々は PDP-11アセンブリのKen Thompsonによって と書かれていましたが、実際にはCに移植した人と話す必要があります。それはおそらく Dennis Ritchie 、彼はUnix用にCを作成し、Cを使用してUnixを非PDPマシンに移植できるようにする多くの人の1人だったためしかし、リッチー博士はそのような質問に答えるのにもはやいません。
コードを読んだところ、編集されたドキュメントの in-core コピーの内容を保存しようとしたことが示唆されました。他のテキストエディターも死なないことに気づくでしょう Ctrl-C。
ed
の機能は次のとおりです Ctrl-C:
_onintr()
{
signal(SIGINT, onintr);
putchr('\n');
lastc = '\n';
error(Q);
}
_
(はい、 K&R C 。戻り値の型指定子やパラメータ宣言は必要ありません。)
英語に翻訳、ed
:
シグナルハンドラを再登録します。
(Unixは自動リセット信号を取得しませんでした 4.3BSDまで 、1980年代中頃。)
グローバル変数lastc
を介して、新しい行を書き出し、そのことを記憶します。
(_ed.c
_には約sixtyグローバル変数があります。)
ユーザーの観点からは、error()
関数を呼び出します。これは 有名な が、印刷_?
_を実行するだけです。
つまり、「そうするつもりはなかったのですか」。
ed
は、他のインタラクティブプログラムと同様に、 Ctrl+C プログラム自体のタスクを中断します。
これは、シェルで実行されているタスク(コマンド)を中断する通常の場合と非常に似ています。
ユーザーの観点からは、両方のバリアントは非常によく似ています。シグナルの処理は異なります。通常の場合、シグナルSIGINT
は実行中のコマンドであるフォアグラウンドプロセスに送信され、コマンドは終了することで処理します。ed
の場合、シグナルはフォアグラウンドプロセスのed
インスタンスに送信されます。 ed
で実行中のタスクがある場合、そのタスクは中断され、プロンプトが表示されます。実行中のタスクがない場合、何も変更されません。
シェルも終了しないことに注意してください Ctrl+C、ed
と同じように。そしてそれが終了すること Ctrl+D。繰り返しますが、ed
のように
ed
が気にする3つのシグナルがあります。
INT
HUP
QUIT
ed
のPOSIX仕様では、これらについて次のように述べています。
SIGINT
ed
ユーティリティは現在のアクティビティを中断し、文字列?\n
を標準出力に書き込み、コマンドモードに戻ります(詳細説明のセクションを参照)。
SIGHUP
バッファが空ではなく、最後の書き込み以降に変更されている場合、
ed
ユーティリティはバッファのコピーをファイルに書き込もうとします。まず、現在のディレクトリにあるed.hup
という名前のファイルを使用します。それが失敗した場合、HOME
環境変数で指定されたディレクトリにあるed.hup
という名前のファイルが使用されます。いずれの場合でも、ed
ユーティリティは、現在記憶されているパス名にファイルを書き込まずに、コマンドモードに戻らずに終了します。
SIGQUIT
ed
ユーティリティはこのイベントを無視します。
したがって、使用しているed
の実装は、INT
信号に関するPOSIX仕様に準拠しています(これは Ctrl+C 送信)。
この点で、エディターはインタラクティブシェルのように動作し、INT
信号を受信しても終了しません。 vi
やnano
などの他のエディターも同じことを行います。