POSIX 環境では非常に多くのエラーが発生する可能性があります。それらのいくつか (特に接続されていないソケットへの書き込みなど) がシグナルの形で特別な扱いを受けるのはなぜですか?
4 に答える
これは設計によるものであり、パイプラインで使用されるテキストを生成する単純なプログラム (find、grep、cat など) は、消費者が死亡すると停止します。つまり、 のようなチェーンを実行している場合find | grep | sed | head
、 head は十分な行を読み取るとすぐに終了します。これにより、sed が SIGPIPE で強制終了され、grep が SIGPIPE で強制終了され、find が SEGPIPE で強制終了されます。SIGPIPE がなければ、素朴に書かれたプログラムは実行を続け、誰も必要としないコンテンツを生成します。
プログラムで SIGPIPE を取得したくない場合は、signal() を呼び出して無視してください。その後、破損したパイプにヒットした write() などのシステムコールは、代わりに errno=EPIPE を返します。
閉じた記述子/ソケットを書き込むと が生成される理由の詳細な説明については、この SO 回答を参照してくださいSIGPIPE
。
SIGPIPE
ソケットに固有のものではありません — 名前が示すように、パイプ (匿名または名前付き) に書き込もうとしたときにも送信されます。別のエラー処理動作を行う理由は、破損したパイプを常にエラーとして処理する必要がないためだと思います (たとえば、存在しないファイルに書き込もうとすると、常にエラーとして処理する必要があります)。
プログラムを考えてみましょうless
。このプログラムはstdin
(ファイル名が指定されていない限り) から入力を読み取り、一度にその一部のみを表示します。ユーザーが下にスクロールすると、 からさらに入力を読み取り、それをstdin
表示しようとします。すべての入力を一度に読み取るわけではないため、入力がすべて読み取られる前にユーザーが (たとえば を押しq
て) 終了すると、パイプが壊れます。ただし、これは実際には問題ではないため、パイプを書き留めているプログラムはそれを適切に処理する必要があります。
それはデザイン次第です。
最初は、シグナルを使用してユーザー空間に送信されたイベント通知を制御しますが、システム呼び出し元がシグナルハンドラーを作成する必要がないポーリングなどのより一般的なスケルトンがあるため、後で必要なくなります。