Fcntl module: Provide equivalents to linux' asm-generic/ioctl.h macros for ioctl's ioc argument

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 a ctypes structure, 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 touching ctype’s underware. Maybe ctype-provided structures should expose that they implement the Buffer interface ?
  • buffer size does not seem to be computable in a unified way. The simplest I could figure out was to create a memoryview and access nbytes. This feels like a waste of a memoryview.

Would merging (for some loose meaning of merging) my module into fcntl be welcome ?

What would be the process ?