サーバ・クライアントプログラムを C で書いて、通信の実験中、
クライアントを Ctrl-c (C-c) で止めると、なぜかサーバも道連れになってしまう。
落ちるところは普通の send()。返り値がいくつ、とかチェックする間もなく落ちてしまう。
でも、クライアントを C-z で一度止めて kill したときには落ちない。
パケットキャプチャしてみると、どちらのケースでも FIN ではなく RST (リセット)パケットが飛んでいる。
いろいろ調べてみると、間が悪くRST パケットが飛んでくると、
SIGPIPE が返される模様。それで、SIGPIPE のシグナルハンドラが動いて、サーバプロセスも
道連れになってしまうみたい。
この挙動を止めるには、以下のように書いて SIGPIPE のシグナルハンドラを無効にする。
#include
...
int main(){
signal( SIGPIPE , SIG_IGN );
でも、man を見ていたら、send のオプションで抑制することもできるらしい。
MSG_NOSIGNAL (Linux 2.2 以降)
ストリーム指向のソケットで相手側が接続を切断した時に、エラーとして
SIGPIPE を送信しないように要求する。この場合でも EPIPE は返される。
ちなみに、sigpipe は、元々パイプでつながったプロセスのために作られたもの。
例えば、
$ grep なんとか | head -10
としたときに、右側の head は 10行読んだら、左の grep の処理はもう不要になってしまう。
こういうとき、左のプロセスに対し、SIGPIPEが送られる。
[an error occurred while processing this directive]