Coverage for linuxpy/ioctl.py: 95%

39 statements  

« 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. 

6 

7"""ioctl helper functions""" 

8 

9import enum 

10import fcntl 

11import logging 

12 

13from .ctypes import calcsize, i32, sizeof 

14 

15NRBITS = 8 

16TYPEBITS = 8 

17SIZEBITS = 14 

18DIRBITS = 2 

19 

20NRSHIFT = 0 

21TYPESHIFT = NRSHIFT + NRBITS 

22SIZESHIFT = TYPESHIFT + TYPEBITS 

23DIRSHIFT = SIZESHIFT + SIZEBITS 

24 

25NONE = 0 

26WRITE = 1 

27READ = 2 

28 

29log = logging.getLogger(__name__) 

30 

31 

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 ) 

48 

49 

50def IO(magic, number): 

51 return IOC(NONE, magic, number, 0) 

52 

53 

54def IOW(magic, number, size): 

55 return IOC(WRITE, magic, number, size) 

56 

57 

58def IOR(magic, number, size): 

59 return IOC(READ, magic, number, size) 

60 

61 

62def IOWR(magic, number, size): 

63 return IOC(READ | WRITE, magic, number, size) 

64 

65 

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