From: Makoto Kishimoto Date: 2012-03-07T10:13:29+09:00 Subject: [ruby-dev:45315] [ruby-trunk - Bug #5429] 64ビットなFreeBSDのioctlでビット31が1なリクエストの時の不具合 Issue #5429 has been updated by Makoto Kishimoto. たいして長くないので添付じゃなくインラインにしますが、 SNDCTL_DSP_SPEED = 0xc0045002 - 0x1_0000_0000 SNDCTL_DSP_STEREO = 0xc0045003 - 0x1_0000_0000 SNDCTL_DSP_SETFMT = 0xc0045005 - 0x1_0000_0000 AFMT_S16_LE = 0x00000010 open("/dev/dsp", "w:ASCII-8BIT"){|dsp| ioarg = [AFMT_S16_LE].pack "i!" dsp.ioctl SNDCTL_DSP_SETFMT, ioarg ioarg = [44100].pack "i!" dsp.ioctl SNDCTL_DSP_SPEED, ioarg ioarg = [1].pack "i!" dsp.ioctl SNDCTL_DSP_STEREO, ioarg loop { buf = STDIN.read 4 break unless buf buf.force_encoding "ASCII-8BIT" dsp.write buf } } こんな感じです。CDからリップした、 > track01.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 16 bit, stereo 44100 Hz こんな感じのwavを標準入力から食わせると音が出ます。 ---------------------------------------- Bug #5429: 64ビットなFreeBSDのioctlでビット31が1なリクエストの時の不具合 https://bugs.ruby-lang.org/issues/5429 Author: Makoto Kishimoto Status: Closed Priority: Normal Assignee: Makoto Kishimoto 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://bugs.ruby-lang.org/