From: Yui NARUSE Date: 2011-10-10T01:52:27+09:00 Subject: [ruby-dev:44590] [Ruby 1.9 - Bug #5429] 64ビットなFreeBSDのioctlでビット31が1なリクエストの時の不具合 Issue #5429 has been updated by Yui NARUSE. ざっと調べてみましたが、 == POSIX int ioctl(int fildes, int request, ... /* arg */); http://pubs.opengroup.org/onlinepubs/9699919799/functions/ioctl.html == AIX int ioctl (fd, request, .../*arg*/) int fd; int request; int .../*arg*/; http://publib.boulder.ibm.com/infocenter/aix/v6r1/topic/com.ibm.aix.commtechref/doc/commtrf2/ioctl.htm == Solaris int ioctl(int fildes, int request, /* arg */ ...); http://download.oracle.com/docs/cd/E19963-01/html/821-1463/ioctl-2.html == HP-UX int ioctl(int fildes, int request, ... /* arg */); http://nixdoc.net/man-pages/HP-UX/man2/ioctl.2.html == Tru64 int ioctl( int fildes, int request, ... /* arg */ ); http://nixdoc.net/man-pages/Tru64/man2/ioctl.2.html == IRIX int ioctl (int fildes, int request, ...); http://nixdoc.net/man-pages/irix/man2/ioctl.2.html == Linux extern int ioctl (int __fd, unsigned long int __request, ...) __THROW; manpageは以下の通りだが、実際のヘッダは異なる。 int ioctl(int d, int request, ...); https://www.kernel.org/doc/man-pages/online/pages/man2/ioctl.2.html == NetBSD int ioctl(int d, unsigned long request, ...); http://netbsd.gw.com/cgi-bin/man-cgi?ioctl+2+NetBSD-current == OpenBSD int ioctl(int d, unsigned long request, ...); http://www.openbsd.org/cgi-bin/man.cgi?query=ioctl&sektion=2&format=html == Darwin int ioctl(int fildes, unsigned long request, ...); http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man2/ioctl.2.html いやー、やっぱり Linux はダメですね!ってのはおいといて、 商用 UNIX は int、それ以外は unsigned long っぽいですね。 ---------------------------------------- Bug #5429: 64ビットなFreeBSDのioctlでビット31が1なリクエストの時の不具合 http://redmine.ruby-lang.org/issues/5429 Author: Makoto Kishimoto Status: Open Priority: Low Assignee: Category: core Target version: 1.9.x ruby -v: ruby 1.9.4dev (2011-10-09 trunk 33439) [x86_64-freebsd8.2] 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