ioctl’s ioc argument value is, at least in some cases, composed of multiple pieces of information:
- transfer direction (read, write, both, neither)
- ioctl number
- ioctl function (when the same ioctl number corresponds to multiple functions)
- buffer size
While in some cases it is enough to hardcode the resulting value (ex: termios.TIOCGPGRPfrom the module’s documentation), in other cases ioctl’s caller would like being able to construct the ioc argument at runtime (ex: hidraw API, …).
Linux asm-generic/ioctl.h header defines a few macros in order to achieve this form C code.
To try to save other developer from code duplication, I implemented the ioctl-opt module (source), which came out as 115 lines of code (plus license header and inline sanity check).
I think the code is short and simple enough that the stdlib fcntl module should provide that functionality, not a 3rd-party module.
I am aware of two python-level minor complications, at least in the way I implemented my module:
- type declaration for arguments which may come from
ctypes(…which seems likely in such case: declare actypesstructure, instantiate it, pass it to an ioctl call, use the result). Specitically, I would like to be able to achieve something like
def IOC_TYPECHECK(t: Buffer | ctypes._CData | type[ctypes._CData]) -> int:
but without touchingctype’s underware. Maybectype-provided structures should expose that they implement theBufferinterface ? - buffer size does not seem to be computable in a unified way. The simplest I could figure out was to create a
memoryviewand accessnbytes. This feels like a waste of amemoryview.
Would merging (for some loose meaning of merging) my module into fcntl be welcome ?
What would be the process ?