高島です。

On Mon, 18 Oct 1999 23:55:14 +0900
"NAKAMURA, Hiroshi" <nakahiro / sarion.co.jp> wrote:

> > From: Yukihiro Matsumoto [mailto:matz / netlab.co.jp]
> > Sent: Tuesday, October 12, 1999 12:26 PM
> 
> > |やっぱりなかださんの書かれている通り,
> > |いちいちエラーチェックをするのが面倒だからということなのかしらん.
> > 
> > そうなんだと信じて、デフォルトはSIG_IGNにするようにしました。
> > まずければ指摘してください。
> 
(省略)
> 送ったつもりになっていたら実はそのPIPEの先を誰も読んでなかった,
> というエラーを(例えEPIPEを拾っていても)検出できないというのは,
> なひにはちょっと気持ち悪いです.ので,
> 今後なひはスクリプトの先頭で,signal handlerを設定すると思います.

Rubyの実装については詳しくないので単なるUnixのソケット(or
PIPE)の話として言えば、「送ったつもりになっていたら実はその
PIPEの先を誰も読んでなかった」場合にはバッファが一杯になるま
でwrite()は成功して、バッファが一杯になったらBLOCKモードであ
ればwrite()はブロックし、NON-BLOCKモードであればwrite()は
EAGAINとかEWOULDBLOCKとかいったエラーで失敗しますので
SIGPIPE(EPIPE)は関係ないと思います。

誰も読んでいなかったというのが、相手がソケット(or PIPE)を
close()していたという場合のみSIGPIPE(EPIPE)が発生しますが、
これは1バイトでもwrite()した瞬間に分かります。

ですから、基本的にSIGPIPEによる処理とEPIPEによる処理に違いは
ないと思います。


なお、厳密には、ほとんどのUnixのシグナルは、複数発生した場合
に例えNODEFERとしていても全部を受けきれる保証はありません
(100回SIGPIPEが発生しても99回しかSIGPIPEのハンドラは呼ばれな
いかもしれない)から、EPIPEによるエラー処理は確実である
(write()と同期してエラーが検出される)のに対してSIGPIPEによる
処理は確実ではない(異なるソケット(or PIPE)に立て続けに発行し
たwrite()がすべて失敗しても、その回数分のSIGPIPEハンドラが呼
ばれないかもしれないし、そもそもどのソケット(or PIPE)に対し
てエラーが発生したのかも分からない)とも言えると思います。

# もしかして、LinuxとかのUnix-like OSでは違ったりするのかな??


--
高島真 (tksmmkt / coral.ocn.ne.jp)