ruby/perl のsyswrite について話したあとばたんと寝てたら、寝てる間に ruby コミッタと linux kernel コミッタがやってきて write(2) の制約であることが明らかになっていた
@frsyuki んでもこれってちょいおかしくないですか? size_t では SSIZE_MAX 以上は普通表すことができないですよね
2013-03-15 01:43:36@tagomoris size_t は unsigned だけど、ssize_t は signed なので、ssize_t の方が1ビット短い。
2013-03-15 01:45:34write(2) の返り値が ssize_t だから、そもそも SSIZE_MAX を超えたら途中で帰らないとエラーか正常終了か返り値で区別できなくなるんだな
2013-03-15 01:46:24@frsyuki まあ、とはいえこれはサイズ指定にまつわる型のミスマッチの問題であって、バッファリング云々とは関係ないすね
2013-03-15 01:46:45SSIZE_MAX を超えるデータ量の write はblockingであっても全部書かずに戻ることがある、か。うーん。
2013-03-15 01:47:31@tagomoris SSIZE_MAX を超えたり、シグナルを受け取ることが想定されるとか、指定バイト数に満たないバイト数で帰ってきたときに発生したエラーを知りたい場合には、writeを繰り返し呼ぶ必要がある…というところでしょうか。
2013-03-15 01:49:45@frsyuki SSIZE_MAX以上はちょっと特殊な気がするので置いておくと、普通はsignalくらいかなーという気がしますね。その場合はどっちにしろsignal trapがという話で、writeの返り値がcount指定値より少ないときはエラー、でいい気がします。
2013-03-15 01:51:58@tagomoris signalの扱いはケースバイケースだと思いますが、そうなりますね。もう一回だけsyswriteを呼んで、何が原因で書けなかったかをエラーログに含めるのは親切だと思いました!
2013-03-15 01:55:45仮にシグナル割り込みで write が途中で帰ってきたとして、もう一度 write を読んだら成功してしまうんでは…シグナル割り込みが原因で write が途中で帰ってきたことを知る方法は…?
2013-03-15 01:59:14@frsyuki あれ、いや、blockingなら途中まで書き込めたバイト数が帰ってくると同時に errno がセットされるんじゃ?
2013-03-15 01:59:46@tagomoris The next write of a non-zero number of bytes would give a failure return (except as noted below) もう一回呼ぶのかと http://t.co/6MJSBrhv36
2013-03-15 02:01:35"If write() is interrupted by a signal before it writes any data, it shall return -1 with errno set to [EINTR]."
2013-03-15 02:03:30