首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >python - ioctl编号可能与C ioctl编号不同吗?

python - ioctl编号可能与C ioctl编号不同吗?
EN

Stack Overflow用户
提问于 2012-07-14 17:10:03
回答 2查看 3K关注 0票数 1

据我所知,ioctl编号由驱动程序很好地定义,并在内核中注册。

我正在使用python中的一些代码来查询操纵杆状态。我读过this doc about joystick apithis doc about ioctl numbersthis one from python fcntl module

我已经创建了一个用于测试和查询值的C程序,python使用我为实现_IOR() C宏而采用的from here代码进行了测试。

内核驱动程序定义:

代码语言:javascript
复制
monolith@monolith ~/temp $ grep JSIOCGAXES /usr/include/* -r
/usr/include/linux/joystick.h:#define JSIOCGAXES        _IOR('j', 0x11, __u8)

C程序

代码语言:javascript
复制
#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程序输出:

代码语言:javascript
复制
monolith@monolith ~/temp $ ./test 
Ioctl Number: (int)-2147390959  (hex)80016a11
Number of axes: 6

Python输出

代码语言:javascript
复制
# 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对象中丢弃了这个错误。

也许问题出在数字转换和类型上,没有idea...clues?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-14 18:52:39

我要回答我自己的问题。

出于某些原因,使用ioctl()从python获取值的唯一方法是发出以下代码:

代码语言:javascript
复制
>>> buf = array.array('h', [0])
>>> fcntl.ioctl(file.fileno(), 0x80016a11, buf)
0
>>> buf[0]
6

也就是说,使用缓冲区来存储结果。我应该重新阅读文档,并理解为什么fcntl.ioctl(file.fileno(), 0x80016a11)不能工作。

票数 2
EN

Stack Overflow用户

发布于 2012-07-14 17:43:16

这一切都归结为十六进制转换是不同的-将十六进制C插入到Python中会给出一个不同的数字:

代码语言:javascript
复制
>>> 0x80016a11
2147576337

我不确定为什么Python和C给出了不同的十六进制,但它可能至少部分与sign有关-Python的'%x'给出了有符号的十六进制值1printfs给出了无符号的2

使用Python十六进制值(-7ffe95ef)可能会有所改善-或者,更好的做法是,像在C中那样使用变量并避免转换错误:

代码语言:javascript
复制
op = _IOR(ord('j'), 0x11, 'c')
...
fcntl.ioctl(file, op)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11482468

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档