ruby/perl のsyswrite について話したあとばたんと寝てたら、寝てる間に ruby コミッタと linux kernel コミッタがやってきて write(2) の制約であることが明らかになっていた
"If write() is interrupted by a signal after it successfully writes some data, it shall return the number of bytes written."
2013-03-15 02:03:34全データが書き込めたかどうかは(シグナルを気にするなら)blocking modeでもチェックしないといけないが、正の書き込みバイト数が帰ってきていてかつそれが書き込み要求サイズより小さかったとしても、それがシグナル由来であるかどうかを気にする必要はない
2013-03-15 02:05:17@frsyuki 成功します。write 途中の原因がシグナルかの判定は、シグナルハンドラーで受信フラグをセットして、write が途中で返ってきたときにそれを見る、でできるかと思いますが、そんな実装見たことあったかな。シグナル受信で write を途中で放棄したい理由は?
2013-03-15 02:27:00@satoh_fumiyasu @tagomoris 基本的にはシグナルを受け取っても継続させたいですね。個人的には単純にユーザー空間でループを回せばいいんでは?派です。
2013-03-15 02:30:54@frsyuki @satoh_fumiyasu それで正しいんだと思います。これっすね。 http://t.co/pMksEt5aLj シグナル自体はどっちにしろどこかでトラップしないとプロセス落ちるだけだし。
2013-03-15 02:33:05@frsyuki @tagomoris なら write(2) は指定バイト未満で返る可能性があることを前提にループするだけです。ただし、wirte が -1 が返したら errno!=EINTR ならエラーで抜ける。https://t.co/ZFOW3gPqbG
2013-03-15 02:38:52@satoh_fumiyasu @frsyuki @tagomoris システムコールがシグナルで割り込まれても勝手に再開するように、シグナルに SA_RESTART フラグ付けておく、という方法も。
2013-03-15 02:41:45read(2), write(2) を使った処理はどう実装すべきか、は今だに自信がない…。
2013-03-15 02:49:27だれかこれの理由おしえて RT @frsyuki: @tagomoris rubyのsyswriteですが、2GBは書いてくれないですねぇ。https://t.co/HH3YBDQHT5
2013-03-15 03:53:09@kosaki55tea @frsyuki @tagomoris ぱっと思いつくのは32bit linuxだからですけど、まさかそんなことはないですよね
2013-03-15 03:55:24@nalsh @frsyuki @tagomoris 32bitでも2GBは書けるべきなのでは?という疑問だったんですが、書けないもん?
2013-03-15 03:56:06@kosaki55tea @frsyuki @tagomoris CRubyのStringやArrayの最大長などがlongのサイズに依存しているという非常に遺憾な仕様がありまして、現代では 32bit Unixはもちろん、msin64で泣けることになっております
2013-03-15 03:58:23@nalsh @frsyuki @tagomoris longのサイズより4kぐらい小さいのはRubyがなんか中でやってるってこと?
2013-03-15 04:00:33@nalsh @kosaki55tea 実行したのは ruby 1.9.3p327 (2012-11-10 revision 37606) [x86_64-linux] です。
2013-03-15 04:00:36@nalsh @kosaki55tea @frsyuki @tagomoris 修正しようにも、CRubyのソースコードで関係あるlongを丁寧に書き換えることはもちろん、C拡張ライブラリのABI互換性・ソースコード互換性を派手にぶちこわすことになるのでなかなか……
2013-03-15 04:00:41@kosaki55tea @frsyuki @tagomoris いやぁ、単にわたしの32bitだからって推測が間違っていて別の理由なんでしょう
2013-03-15 04:01:41@nalsh @frsyuki @tagomoris よく考えたらオレ、コミッタなんだから自分で知れべれるんだった。ちょっとマテ
2013-03-15 04:02:55@kosaki55tea @frsyuki @tagomoris コミッタじゃなくたってgrepでわかる範囲じゃろ。で、longとsize_tにしか依存してないのでCRuby無罪かなぁ
2013-03-15 04:04:27@kosaki55tea @frsyuki @nalsh @tagomoris そして仮想マシンのメモリが少なすぎて実行できないという罠
2013-03-15 04:06:14@kosaki55tea @frsyuki @nalsh @tagomoris あ、できた。straceの結果、rubyは2GBのwriteをするが、カーネルが拒否ってるな。でrubyのsys writeの仕様
2013-03-15 04:11:30