据我所知,ioctl 编号由驱动程序很好地定义并在内核中注册。
我正在使用 python 中的一些代码来查询操纵杆状态。我已经阅读了这个关于游戏杆 api的文档,这个关于 ioctl numbers的文档,以及这个来自 python fcntl 模块的文档。
我创建了一个用于测试和查询值的 C 程序,并且 python 使用我从这里获取的用于实现_IOR()
C 宏的代码进行测试。
内核驱动定义:
monolith@monolith ~/temp $ grep JSIOCGAXES /usr/include/* -r
/usr/include/linux/joystick.h:#define JSIOCGAXES _IOR('j', 0x11, __u8)
C程序
#include <stdio.h>
#include <linux/joystick.h>
#include <fcntl.h>
int main() {
int fd = open("/dev/input/js0", O_RDONLY);
printf("Ioctl Number: (int)%d (hex)%x\n", JSIOCGAXES, JSIOCGAXES);
char number;
ioctl(fd, JSIOCGAXES, &number);
printf("Number of axes: %d\n", number);
close(fd);
return 0;
}
C程序输出:
monolith@monolith ~/temp $ ./test
Ioctl Number: (int)-2147390959 (hex)80016a11
Number of axes: 6
Python 输出
# check if _IOR results in the used ioctl number in C
>>> _IOR(ord('j'), 0x11, 'c')
-2147390959
>>> file = open("/dev/input/js0")
# use that integer
>>> fcntl.ioctl(file, -2147390959)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 14] Bad address
# ask what hex value is
>>> "%x" % -2147390959
'-7ffe95ef'
# WHY THIS HEX CONVERSION DIFFERS?
>>> fcntl.ioctl(file, -0x7ffe95ef)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 14] Bad address
# Use the hex value from the C program output
>>> fcntl.ioctl(file, 0x80016a11)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 14] Bad address
有什么想法为什么我不能用那个 ioctl 号查询文件描述符?ioctl()
并且fcntl()
函数采用文件描述符或具有fileno()
实现方法的对象,因此我从对象中剔除错误file
。
也许问题来自数字转换和类型,不知道......线索?