In my Python (2.7.3) code, I\'m trying to use an ioctl call, accepting a long in
ID: 3538158 • Letter: I
Question
In my Python (2.7.3) code, I'm trying to use an ioctl call, accepting a long int (64 bit) as an argument. I'm on a 64-bit system, so a 64-bit int is the same size as a pointer.
In existing C code, I'd use the call like this (for some file descriptor fd, and request codes IOC_SET_VAL, IOC_GET_VAL):
uint64_t val_in = (uint64_t)1<<32;
int ret;
ret = ioctl(fd,_IOWR(0,IOC_SET_VAL,void*),val_in);
uint64_t val_out;
ret = ioctl(fd,_IOWR(0,IOC_GET_VAL,void*),&val_out); // val_out == val_in
In python, I open the device file, and then I get the following results:
from fcntl import ioctl
ioctl(fd, IOC_SET_VAL, 1<<30)
struct.unpack("L",ioctl(fd, IOC_GET_VAL," "*8)[0] # gives 1<<30
ioctl(fd, IOC_SET_VAL, 1<<32) # gives error:
# OverflowError: signed integer is greater than maximum
ioctl(fd, IOC_SET_VAL, struct.pack("L", 1<<32))
struct.unpack("L",ioctl(fd, IOC_GET_VAL," "*8)[0] # does not give 1<<32 -
# gives 64-bit pointer
As far as I can tell, the arg parameter of Python's ioctl() can be either a 32-bit int or a 64-bit pointer - but what I need is to pass a 64-bit int.
Is there any way Python can do this?
Explanation / Answer
It might be possible using Python's built-in ioctl(), but it's really difficult to test anything.
If nothing else works, you should be able to call the underlying C function directly using the ctypes module, but it's platform-specific.
Assuming Linux, something like this ought to work...
from ctypes import *
libc = CDLL('libc.so.6')
fd = c_int(something)
IOC_SET_VAL = c_int(something)
IOC_GET_VAL = c_int(something)
value = c_uint64(something)
# To set the value
libc.ioctl(fd, IOC_SET_VAL, value)
# To get the value
libc.ioctl(fd, IOC_GET_VAL, byref(value))
...but, again, I can't really test it.
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.