nix/sys/ioctl/
linux.rs

1/// The datatype used for the ioctl number
2#[cfg(any(target_os = "android", target_env = "musl"))]
3#[doc(hidden)]
4pub type ioctl_num_type = ::libc::c_int;
5#[cfg(not(any(target_os = "android", target_env = "musl")))]
6#[doc(hidden)]
7pub type ioctl_num_type = ::libc::c_ulong;
8/// The datatype used for the 3rd argument
9#[doc(hidden)]
10pub type ioctl_param_type = ::libc::c_ulong;
11
12#[doc(hidden)]
13pub const NRBITS: ioctl_num_type = 8;
14#[doc(hidden)]
15pub const TYPEBITS: ioctl_num_type = 8;
16
17#[cfg(any(target_arch = "mips", target_arch = "mips64", target_arch = "powerpc", target_arch = "powerpc64", target_arch = "sparc64"))]
18mod consts {
19    #[doc(hidden)]
20    pub const NONE: u8 = 1;
21    #[doc(hidden)]
22    pub const READ: u8 = 2;
23    #[doc(hidden)]
24    pub const WRITE: u8 = 4;
25    #[doc(hidden)]
26    pub const SIZEBITS: u8 = 13;
27    #[doc(hidden)]
28    pub const DIRBITS: u8 = 3;
29}
30
31// "Generic" ioctl protocol
32#[cfg(any(target_arch = "x86",
33          target_arch = "arm",
34          target_arch = "s390x",
35          target_arch = "x86_64",
36          target_arch = "aarch64",
37          target_arch = "riscv64"))]
38mod consts {
39    #[doc(hidden)]
40    pub const NONE: u8 = 0;
41    #[doc(hidden)]
42    pub const READ: u8 = 2;
43    #[doc(hidden)]
44    pub const WRITE: u8 = 1;
45    #[doc(hidden)]
46    pub const SIZEBITS: u8 = 14;
47    #[doc(hidden)]
48    pub const DIRBITS: u8 = 2;
49}
50
51pub use self::consts::*;
52
53#[doc(hidden)]
54pub const NRSHIFT: ioctl_num_type = 0;
55#[doc(hidden)]
56pub const TYPESHIFT: ioctl_num_type = NRSHIFT + NRBITS as ioctl_num_type;
57#[doc(hidden)]
58pub const SIZESHIFT: ioctl_num_type = TYPESHIFT + TYPEBITS as ioctl_num_type;
59#[doc(hidden)]
60pub const DIRSHIFT: ioctl_num_type = SIZESHIFT + SIZEBITS as ioctl_num_type;
61
62#[doc(hidden)]
63pub const NRMASK: ioctl_num_type = (1 << NRBITS) - 1;
64#[doc(hidden)]
65pub const TYPEMASK: ioctl_num_type = (1 << TYPEBITS) - 1;
66#[doc(hidden)]
67pub const SIZEMASK: ioctl_num_type = (1 << SIZEBITS) - 1;
68#[doc(hidden)]
69pub const DIRMASK: ioctl_num_type = (1 << DIRBITS) - 1;
70
71/// Encode an ioctl command.
72#[macro_export]
73#[doc(hidden)]
74macro_rules! ioc {
75    ($dir:expr, $ty:expr, $nr:expr, $sz:expr) => (
76        (($dir as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::DIRMASK) << $crate::sys::ioctl::DIRSHIFT) |
77        (($ty as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::TYPEMASK) << $crate::sys::ioctl::TYPESHIFT) |
78        (($nr as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::NRMASK) << $crate::sys::ioctl::NRSHIFT) |
79        (($sz as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::SIZEMASK) << $crate::sys::ioctl::SIZESHIFT))
80}
81
82/// Generate an ioctl request code for a command that passes no data.
83///
84/// This is equivalent to the `_IO()` macro exposed by the C ioctl API.
85///
86/// You should only use this macro directly if the `ioctl` you're working
87/// with is "bad" and you cannot use `ioctl_none!()` directly.
88///
89/// # Example
90///
91/// ```
92/// # #[macro_use] extern crate nix;
93/// const KVMIO: u8 = 0xAE;
94/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03));
95/// # fn main() {}
96/// ```
97#[macro_export(local_inner_macros)]
98macro_rules! request_code_none {
99    ($ty:expr, $nr:expr) => (ioc!($crate::sys::ioctl::NONE, $ty, $nr, 0))
100}
101
102/// Generate an ioctl request code for a command that reads.
103///
104/// This is equivalent to the `_IOR()` macro exposed by the C ioctl API.
105///
106/// You should only use this macro directly if the `ioctl` you're working
107/// with is "bad" and you cannot use `ioctl_read!()` directly.
108///
109/// The read/write direction is relative to userland, so this
110/// command would be userland is reading and the kernel is
111/// writing.
112#[macro_export(local_inner_macros)]
113macro_rules! request_code_read {
114    ($ty:expr, $nr:expr, $sz:expr) => (ioc!($crate::sys::ioctl::READ, $ty, $nr, $sz))
115}
116
117/// Generate an ioctl request code for a command that writes.
118///
119/// This is equivalent to the `_IOW()` macro exposed by the C ioctl API.
120///
121/// You should only use this macro directly if the `ioctl` you're working
122/// with is "bad" and you cannot use `ioctl_write!()` directly.
123///
124/// The read/write direction is relative to userland, so this
125/// command would be userland is writing and the kernel is
126/// reading.
127#[macro_export(local_inner_macros)]
128macro_rules! request_code_write {
129    ($ty:expr, $nr:expr, $sz:expr) => (ioc!($crate::sys::ioctl::WRITE, $ty, $nr, $sz))
130}
131
132/// Generate an ioctl request code for a command that reads and writes.
133///
134/// This is equivalent to the `_IOWR()` macro exposed by the C ioctl API.
135///
136/// You should only use this macro directly if the `ioctl` you're working
137/// with is "bad" and you cannot use `ioctl_readwrite!()` directly.
138#[macro_export(local_inner_macros)]
139macro_rules! request_code_readwrite {
140    ($ty:expr, $nr:expr, $sz:expr) => (ioc!($crate::sys::ioctl::READ | $crate::sys::ioctl::WRITE, $ty, $nr, $sz))
141}