的64位参数fcntl.ioctl公司()

2024-06-06 15:40:20 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

这是我的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代码中,我使用如下调用:

^{pr2}$

在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()?


Tags: importcmdisdriverargstructlongint
2条回答

Python的ioctl中的“arg”符号与C的符号不同

在python中(同样根据1),它要么是python整数(不指定32位或64位),要么是某种缓冲区对象(如字符串)。在Python中并没有真正的“指针”(所以所有的底层架构细节——比如32位或64位地址)都被完全隐藏了。在

如果我理解正确的话,您需要的是一个SET_VALstruct.pack(your 64-bit integer)的字符串,然后将这个字符串传递给ioctl,而不是直接传递整数。在

像这样:

struct.pack('>Q',1<<32)

对于GET_VAL,您需要再次使用“Q”类型(而不是“L”)来正确解压64位整数值。在

使用Python的fcntl.ioctl()是否可以实现这一点取决于系统。通过源代码跟踪,错误消息来自对line 658 of ^{}的以下测试。。。在

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

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

^{pr2}$

…大概是(2 ** ((sizeof(int) * 8) - 1)) - 1。在

因此,除非您正在使用的系统中sizeof(int)至少是{},否则您必须直接使用^{}模块调用底层的C函数,但它是特定于平台的。在

假设是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)

相关问题 更多 >