gpt4 book ai didi

python - fcntl.ioctl() 的 64 位参数

转载 作者:太空狗 更新时间:2023-10-30 00:45:33 27 4
gpt4 key购买 nike

在我的 Python (2.7.3) 代码中,我尝试使用 ioctl 调用,接受一个 long int(64 位)作为参数。我在 64 位系统上,因此 64 位 int 与指针的大小相同。

我的问题是 Python 似乎不接受 64 位 int 作为 fcntl.ioctl() 调用的参数。 它很乐意接受 32 位 int 或 64-位指针 - 但我需要传递一个 64 位整数。

这是我的 ioctl 处理程序:

static long trivial_driver_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
long err = 0;

switch (cmd)
{
case 1234:
printk("=== (%u) Driver got arg %lx; arg<<32 is %lx\n", cmd, arg, arg<<32);
break;
case 5678:
printk("=== (%u) Driver got arg %lx\n", cmd, arg);
break;
default:
printk("=== OH NOES!!! %u %lu\n", cmd, arg);
err = -EINVAL;
}

return err;
}

在现有的 C 代码中,我使用这样的调用:

static int trivial_ioctl_test(){
int ret;
int fd = open(DEV_NAME, O_RDWR);

unsigned long arg = 0xffff;

ret = ioctl(fd, 1234, arg); // ===(1234) Driver got arg ffff; arg<<32 is ffff00000000
arg = arg<<32;
ret = ioctl(fd, 5678, arg); // === (5678) Driver got arg ffff00000000
close(fd);

}

在 python 中,我打开设备文件,然后得到以下结果:

>>> from fcntl import ioctl
>>> import os
>>> fd = os.open (DEV_NAME, os.O_RDWR, 0666)
>>> ioctl(fd, 1234, 0xffff)
0
>>> arg = 0xffff<<32
>>> # Kernel log: === (1234) Driver got arg ffff; arg<<32 is ffff00000000
>>> # This demonstrates that ioctl() happily accepts a 32-bit int as an argument.
>>> import struct
>>> ioctl(fd, 5678, struct.pack("L",arg))
'\x00\x00\x00\x00\xff\xff\x00\x00'
>>> # Kernel log: === (5678) Driver got arg 7fff9eb1fcb0
>>> # This demonstrates that ioctl() happily accepts a 64-bit pointer as an argument.
>>> ioctl(fd, 5678, arg)

Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module>
ioctl(fd, 5678, arg)
OverflowError: signed integer is greater than maximum
>>> # Kernel log: (no change - OverflowError is within python)
>>> # Oh no! Can't pass a 64-bit int!
>>>

Python 有什么方法可以将我的 64 位参数传递给 ioctl() 吗?

最佳答案

使用 Python 的 fcntl.ioctl() 是否可行将取决于系统。追溯源码,错误信息来自以下测试 line 658 of getargs.c ...

else if (ival > INT_MAX) {
PyErr_SetString(PyExc_OverflowError,
"signed integer is greater than maximum");
RETURN_ERR_OCCURRED;
}

...在我的系统上,/usr/include/limits.h 告诉我...

#  define INT_MAX   2147483647

...这是(大概)(2 ** ((sizeof(int) * 8) - 1)) - 1

因此,除非您在 sizeof(int) 至少为 8 的系统上工作,否则您必须直接使用ctypes模块,但它是特定于平台的。

假设是 Linux,这样的东西应该可以工作...

from ctypes import *

libc = CDLL('libc.so.6')

fd = os.open (DEV_NAME, os.O_RDWR, 0666)
value = c_uint64(0xffff<<32)
libc.ioctl(fd, 5678, value)

关于python - fcntl.ioctl() 的 64 位参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17210650/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com