Copy _IOR/_IOWR constants from kernel headers and use with fcntl.iocl()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | #!/usr/bin/python2
"""
Linux ioctl numbers made easy
size can be an integer or format string compatible with struct module
for example include/linux/watchdog.h:
#define WATCHDOG_IOCTL_BASE 'W'
struct watchdog_info {
__u32 options; /* Options the card/driver supports */
__u32 firmware_version; /* Firmware version of the card */
__u8 identity[32]; /* Identity of the board */
};
#define WDIOC_GETSUPPORT _IOR(WATCHDOG_IOCTL_BASE, 0, struct watchdog_info)
becomes:
WDIOC_GETSUPPORT = _IOR(ord('W'), 0, "=II32s")
"""
import struct
# constant for linux portability
_IOC_NRBITS = 8
_IOC_TYPEBITS = 8
# architecture specific
_IOC_SIZEBITS = 14
_IOC_DIRBITS = 2
_IOC_NRMASK = (1 << _IOC_NRBITS) - 1
_IOC_TYPEMASK = (1 << _IOC_TYPEBITS) - 1
_IOC_SIZEMASK = (1 << _IOC_SIZEBITS) - 1
_IOC_DIRMASK = (1 << _IOC_DIRBITS) - 1
_IOC_NRSHIFT = 0
_IOC_TYPESHIFT = _IOC_NRSHIFT + _IOC_NRBITS
_IOC_SIZESHIFT = _IOC_TYPESHIFT + _IOC_TYPEBITS
_IOC_DIRSHIFT = _IOC_SIZESHIFT + _IOC_SIZEBITS
_IOC_NONE = 0
_IOC_WRITE = 1
_IOC_READ = 2
def _IOC(dir, type, nr, size):
if isinstance(size, str) or isinstance(size, unicode):
size = struct.calcsize(size)
return dir << _IOC_DIRSHIFT | \
type << _IOC_TYPESHIFT | \
nr << _IOC_NRSHIFT | \
size << _IOC_SIZESHIFT
def _IO(type, nr): return _IOC(_IOC_NONE, type, nr, 0)
def _IOR(type, nr, size): return _IOC(_IOC_READ, type, nr, size)
def _IOW(type, nr, size): return _IOC(_IOC_WRITE, type, nr, size)
def _IOWR(type, nr, size): return _IOC(_IOC_READ | _IOC_WRITE, type, nr, size)
|