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 = "riscv32",
38          target_arch = "riscv64"))]
39mod consts {
40    #[doc(hidden)]
41    pub const NONE: u8 = 0;
42    #[doc(hidden)]
43    pub const READ: u8 = 2;
44    #[doc(hidden)]
45    pub const WRITE: u8 = 1;
46    #[doc(hidden)]
47    pub const SIZEBITS: u8 = 14;
48    #[doc(hidden)]
49    pub const DIRBITS: u8 = 2;
50}
51
52pub use self::consts::*;
53
54#[doc(hidden)]
55pub const NRSHIFT: ioctl_num_type = 0;
56#[doc(hidden)]
57pub const TYPESHIFT: ioctl_num_type = NRSHIFT + NRBITS as ioctl_num_type;
58#[doc(hidden)]
59pub const SIZESHIFT: ioctl_num_type = TYPESHIFT + TYPEBITS as ioctl_num_type;
60#[doc(hidden)]
61pub const DIRSHIFT: ioctl_num_type = SIZESHIFT + SIZEBITS as ioctl_num_type;
62
63#[doc(hidden)]
64pub const NRMASK: ioctl_num_type = (1 << NRBITS) - 1;
65#[doc(hidden)]
66pub const TYPEMASK: ioctl_num_type = (1 << TYPEBITS) - 1;
67#[doc(hidden)]
68pub const SIZEMASK: ioctl_num_type = (1 << SIZEBITS) - 1;
69#[doc(hidden)]
70pub const DIRMASK: ioctl_num_type = (1 << DIRBITS) - 1;
71
72/// Encode an ioctl command.
73#[macro_export]
74#[doc(hidden)]
75macro_rules! ioc {
76    ($dir:expr, $ty:expr, $nr:expr, $sz:expr) => (
77        (($dir as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::DIRMASK) << $crate::sys::ioctl::DIRSHIFT) |
78        (($ty as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::TYPEMASK) << $crate::sys::ioctl::TYPESHIFT) |
79        (($nr as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::NRMASK) << $crate::sys::ioctl::NRSHIFT) |
80        (($sz as $crate::sys::ioctl::ioctl_num_type & $crate::sys::ioctl::SIZEMASK) << $crate::sys::ioctl::SIZESHIFT))
81}
82
83/// Generate an ioctl request code for a command that passes no data.
84///
85/// This is equivalent to the `_IO()` macro exposed by the C ioctl API.
86///
87/// You should only use this macro directly if the `ioctl` you're working
88/// with is "bad" and you cannot use `ioctl_none!()` directly.
89///
90/// # Example
91///
92/// ```
93/// # #[macro_use] extern crate nix;
94/// const KVMIO: u8 = 0xAE;
95/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03));
96/// # fn main() {}
97/// ```
98#[macro_export(local_inner_macros)]
99macro_rules! request_code_none {
100    ($ty:expr, $nr:expr) => (ioc!($crate::sys::ioctl::NONE, $ty, $nr, 0))
101}
102
103/// Generate an ioctl request code for a command that reads.
104///
105/// This is equivalent to the `_IOR()` macro exposed by the C ioctl API.
106///
107/// You should only use this macro directly if the `ioctl` you're working
108/// with is "bad" and you cannot use `ioctl_read!()` directly.
109///
110/// The read/write direction is relative to userland, so this
111/// command would be userland is reading and the kernel is
112/// writing.
113#[macro_export(local_inner_macros)]
114macro_rules! request_code_read {
115    ($ty:expr, $nr:expr, $sz:expr) => (ioc!($crate::sys::ioctl::READ, $ty, $nr, $sz))
116}
117
118/// Generate an ioctl request code for a command that writes.
119///
120/// This is equivalent to the `_IOW()` macro exposed by the C ioctl API.
121///
122/// You should only use this macro directly if the `ioctl` you're working
123/// with is "bad" and you cannot use `ioctl_write!()` directly.
124///
125/// The read/write direction is relative to userland, so this
126/// command would be userland is writing and the kernel is
127/// reading.
128#[macro_export(local_inner_macros)]
129macro_rules! request_code_write {
130    ($ty:expr, $nr:expr, $sz:expr) => (ioc!($crate::sys::ioctl::WRITE, $ty, $nr, $sz))
131}
132
133/// Generate an ioctl request code for a command that reads and writes.
134///
135/// This is equivalent to the `_IOWR()` macro exposed by the C ioctl API.
136///
137/// You should only use this macro directly if the `ioctl` you're working
138/// with is "bad" and you cannot use `ioctl_readwrite!()` directly.
139#[macro_export(local_inner_macros)]
140macro_rules! request_code_readwrite {
141    ($ty:expr, $nr:expr, $sz:expr) => (ioc!($crate::sys::ioctl::READ | $crate::sys::ioctl::WRITE, $ty, $nr, $sz))
142}