/rust/registry/src/index.crates.io-6f17d22bba15001f/rustix-0.38.34/src/ioctl/linux.rs
Line | Count | Source (jump to first uncovered line) |
1 | | //! `ioctl` opcode behavior for Linux platforms. |
2 | | |
3 | | use super::{Direction, RawOpcode}; |
4 | | use consts::*; |
5 | | |
6 | | /// Compose an opcode from its component parts. |
7 | 0 | pub(super) const fn compose_opcode( |
8 | 0 | dir: Direction, |
9 | 0 | group: RawOpcode, |
10 | 0 | num: RawOpcode, |
11 | 0 | size: RawOpcode, |
12 | 0 | ) -> RawOpcode { |
13 | | macro_rules! mask_and_shift { |
14 | | ($val:expr, $shift:expr, $mask:expr) => {{ |
15 | | ($val & $mask) << $shift |
16 | | }}; |
17 | | } |
18 | | |
19 | 0 | let dir = match dir { |
20 | 0 | Direction::None => NONE, |
21 | 0 | Direction::Read => READ, |
22 | 0 | Direction::Write => WRITE, |
23 | 0 | Direction::ReadWrite => READ | WRITE, |
24 | | }; |
25 | | |
26 | 0 | mask_and_shift!(group, GROUP_SHIFT, GROUP_MASK) |
27 | 0 | | mask_and_shift!(num, NUM_SHIFT, NUM_MASK) |
28 | 0 | | mask_and_shift!(size, SIZE_SHIFT, SIZE_MASK) |
29 | 0 | | mask_and_shift!(dir, DIR_SHIFT, DIR_MASK) |
30 | 0 | } |
31 | | |
32 | | const NUM_BITS: RawOpcode = 8; |
33 | | const GROUP_BITS: RawOpcode = 8; |
34 | | |
35 | | const NUM_SHIFT: RawOpcode = 0; |
36 | | const GROUP_SHIFT: RawOpcode = NUM_SHIFT + NUM_BITS; |
37 | | const SIZE_SHIFT: RawOpcode = GROUP_SHIFT + GROUP_BITS; |
38 | | const DIR_SHIFT: RawOpcode = SIZE_SHIFT + SIZE_BITS; |
39 | | |
40 | | const NUM_MASK: RawOpcode = (1 << NUM_BITS) - 1; |
41 | | const GROUP_MASK: RawOpcode = (1 << GROUP_BITS) - 1; |
42 | | const SIZE_MASK: RawOpcode = (1 << SIZE_BITS) - 1; |
43 | | const DIR_MASK: RawOpcode = (1 << DIR_BITS) - 1; |
44 | | |
45 | | #[cfg(any( |
46 | | target_arch = "x86", |
47 | | target_arch = "arm", |
48 | | target_arch = "s390x", |
49 | | target_arch = "x86_64", |
50 | | target_arch = "aarch64", |
51 | | target_arch = "riscv32", |
52 | | target_arch = "riscv64", |
53 | | target_arch = "loongarch64", |
54 | | target_arch = "csky" |
55 | | ))] |
56 | | mod consts { |
57 | | use super::RawOpcode; |
58 | | |
59 | | pub(super) const NONE: RawOpcode = 0; |
60 | | pub(super) const READ: RawOpcode = 2; |
61 | | pub(super) const WRITE: RawOpcode = 1; |
62 | | pub(super) const SIZE_BITS: RawOpcode = 14; |
63 | | pub(super) const DIR_BITS: RawOpcode = 2; |
64 | | } |
65 | | |
66 | | #[cfg(any( |
67 | | target_arch = "mips", |
68 | | target_arch = "mips32r6", |
69 | | target_arch = "mips64", |
70 | | target_arch = "mips64r6", |
71 | | target_arch = "powerpc", |
72 | | target_arch = "powerpc64", |
73 | | target_arch = "sparc", |
74 | | target_arch = "sparc64" |
75 | | ))] |
76 | | mod consts { |
77 | | use super::RawOpcode; |
78 | | |
79 | | pub(super) const NONE: RawOpcode = 1; |
80 | | pub(super) const READ: RawOpcode = 2; |
81 | | pub(super) const WRITE: RawOpcode = 4; |
82 | | pub(super) const SIZE_BITS: RawOpcode = 13; |
83 | | pub(super) const DIR_BITS: RawOpcode = 3; |
84 | | } |
85 | | |
86 | | #[cfg(not(any( |
87 | | // These have no ioctl opcodes defined in linux_raw_sys |
88 | | // so can't use that as a known-good value for this test. |
89 | | target_arch = "sparc", |
90 | | target_arch = "sparc64" |
91 | | )))] |
92 | | #[test] |
93 | | fn check_known_opcodes() { |
94 | | use crate::backend::c::{c_long, c_uint}; |
95 | | use core::mem::size_of; |
96 | | |
97 | | // _IOR('U', 15, unsigned int) |
98 | | assert_eq!( |
99 | | compose_opcode( |
100 | | Direction::Read, |
101 | | b'U' as RawOpcode, |
102 | | 15, |
103 | | size_of::<c_uint>() as RawOpcode |
104 | | ), |
105 | | linux_raw_sys::ioctl::USBDEVFS_CLAIMINTERFACE as RawOpcode |
106 | | ); |
107 | | |
108 | | // _IOW('v', 2, long) |
109 | | assert_eq!( |
110 | | compose_opcode( |
111 | | Direction::Write, |
112 | | b'v' as RawOpcode, |
113 | | 2, |
114 | | size_of::<c_long>() as RawOpcode |
115 | | ), |
116 | | linux_raw_sys::ioctl::FS_IOC_SETVERSION as RawOpcode |
117 | | ); |
118 | | } |