Coverage for linuxpy/ioctl.py: 95%
39 statements
« prev ^ index » next coverage.py v7.10.4, created at 2026-02-19 15:10 +0100
« prev ^ index » next coverage.py v7.10.4, created at 2026-02-19 15:10 +0100
1#
2# This file is part of the linuxpy project
3#
4# Copyright (c) 2023 Tiago Coutinho
5# Distributed under the GPLv3 license. See LICENSE for more info.
7"""ioctl helper functions"""
9import enum
10import fcntl
11import logging
13from .ctypes import calcsize, i32, sizeof
15NRBITS = 8
16TYPEBITS = 8
17SIZEBITS = 14
18DIRBITS = 2
20NRSHIFT = 0
21TYPESHIFT = NRSHIFT + NRBITS
22SIZESHIFT = TYPESHIFT + TYPEBITS
23DIRSHIFT = SIZESHIFT + SIZEBITS
25NONE = 0
26WRITE = 1
27READ = 2
29log = logging.getLogger(__name__)
32def IOC(direction, magic, number, size):
33 """Generic IOC call"""
34 if isinstance(magic, str):
35 magic = ord(magic)
36 if isinstance(size, str):
37 size = calcsize(size)
38 elif size is int:
39 size = 4
40 elif not isinstance(size, int):
41 size = sizeof(size)
42 return (
43 i32(direction << DIRSHIFT).value
44 | i32(magic << TYPESHIFT).value
45 | i32(number << NRSHIFT).value
46 | i32(size << SIZESHIFT).value
47 )
50def IO(magic, number):
51 return IOC(NONE, magic, number, 0)
54def IOW(magic, number, size):
55 return IOC(WRITE, magic, number, size)
58def IOR(magic, number, size):
59 return IOC(READ, magic, number, size)
62def IOWR(magic, number, size):
63 return IOC(READ | WRITE, magic, number, size)
66def ioctl(fd, request, *args):
67 req = request.name if isinstance(request, enum.Enum) else request
68 log.debug("request=%s, arg=%s", req, args)
69 fcntl.ioctl(fd, request, *args)
70 return args and args[0] or None