From: Tomoyuki Chikanaga Date: 2011-11-15T01:25:48+09:00 Subject: [ruby-dev:44866] [Backport93 - Backport #5429] 64ビットなFreeBSDのioctlでビット31が1なリクエストの時の不具合 Issue #5429 has been updated by Tomoyuki Chikanaga. あいざわさんのパッチだと、Tempfile.new がブロックを yield しないので、assert を通っていないだけのようです。 SnowLeopard の man fcntl によると [EINVAL] Cmd is F_DUPFD and arg is negative or greater than the maximum allowable number (see getdtablesize(2)). で getdtablesize() は 256 を返すのでとりあえず 500 -> 255 にすると通るようになりました。 500 というのは他の open 済みの fd と重複しない程度に大きな数字ということだと思うので、とりあえず 255 にしてしまってもいいでしょうか。ちゃんと空き fd を確保してそこに dup するようにしたほうがいいのかもしれませんが。 ---------------------------------------- Backport #5429: 64ビットなFreeBSDのioctlでビット31が1なリクエストの時の不具合 http://redmine.ruby-lang.org/issues/5429 Author: Makoto Kishimoto Status: Assigned Priority: Low Assignee: Yuki Sonoda Category: Target version: 64ビットなFreeBSD 8において、ioctl(2)のプロトタイプ宣言は以下のように なっていて、 int ioctl(int d, unsigned long request, ...); ビット31(32ビットであればMSB)が1なリクエストでも、上位ビットがゼロ拡張 された64ビット値を期待しています。 それに対しrubyのtrunkではIO#ioctlの引数の値の範囲は符号付き32ビットに なっていて、最終的にio.cのnogvl_io_cntlに、intを引数としたioctlの 呼び出しがあり、ビット31が1なリクエストは符号拡張されて、ioctlを呼ぶことに なり、 その結果システムメッセージに、(SNDCTL_DSP_SPEED の例) WARNING pid 82043 (initial thread): ioctl sign-extension ioctl ffffffffc0045002 というようなウォーニングが出ます(一応目的の動作はしている)。 回避する修正は (unsigned) とキャストを入れればいいように思うのですが、 他のプラットフォームでの問題や、IO#ioctlの受け入れるべき引数の値の範囲の 問題などがあるので、とりあえずチケットのみ登録します。 -- http://redmine.ruby-lang.org