xref: /third_party/rust/crates/nix/src/sys/ioctl/bsd.rs (revision 3da5c369)
1/// The datatype used for the ioctl number
2#[doc(hidden)]
3#[cfg(not(target_os = "illumos"))]
4pub type ioctl_num_type = ::libc::c_ulong;
5
6#[doc(hidden)]
7#[cfg(target_os = "illumos")]
8pub type ioctl_num_type = ::libc::c_int;
9
10/// The datatype used for the 3rd argument
11#[doc(hidden)]
12pub type ioctl_param_type = ::libc::c_int;
13
14mod consts {
15    use crate::sys::ioctl::ioctl_num_type;
16    #[doc(hidden)]
17    pub const VOID: ioctl_num_type = 0x2000_0000;
18    #[doc(hidden)]
19    pub const OUT: ioctl_num_type = 0x4000_0000;
20    #[doc(hidden)]
21    #[allow(overflowing_literals)]
22    pub const IN: ioctl_num_type = 0x8000_0000;
23    #[doc(hidden)]
24    pub const INOUT: ioctl_num_type = IN | OUT;
25    #[doc(hidden)]
26    pub const IOCPARM_MASK: ioctl_num_type = 0x1fff;
27}
28
29pub use self::consts::*;
30
31#[macro_export]
32#[doc(hidden)]
33macro_rules! ioc {
34    ($inout:expr, $group:expr, $num:expr, $len:expr) => {
35        $inout
36            | (($len as $crate::sys::ioctl::ioctl_num_type
37                & $crate::sys::ioctl::IOCPARM_MASK)
38                << 16)
39            | (($group as $crate::sys::ioctl::ioctl_num_type) << 8)
40            | ($num as $crate::sys::ioctl::ioctl_num_type)
41    };
42}
43
44/// Generate an ioctl request code for a command that passes no data.
45///
46/// This is equivalent to the `_IO()` macro exposed by the C ioctl API.
47///
48/// You should only use this macro directly if the `ioctl` you're working
49/// with is "bad" and you cannot use `ioctl_none!()` directly.
50///
51/// # Example
52///
53/// ```
54/// # #[macro_use] extern crate nix;
55/// const KVMIO: u8 = 0xAE;
56/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03));
57/// # fn main() {}
58/// ```
59#[macro_export(local_inner_macros)]
60macro_rules! request_code_none {
61    ($g:expr, $n:expr) => {
62        ioc!($crate::sys::ioctl::VOID, $g, $n, 0)
63    };
64}
65
66/// Generate an ioctl request code for a command that passes an integer
67///
68/// This is equivalent to the `_IOWINT()` macro exposed by the C ioctl API.
69///
70/// You should only use this macro directly if the `ioctl` you're working
71/// with is "bad" and you cannot use `ioctl_write_int!()` directly.
72#[macro_export(local_inner_macros)]
73macro_rules! request_code_write_int {
74    ($g:expr, $n:expr) => {
75        ioc!(
76            $crate::sys::ioctl::VOID,
77            $g,
78            $n,
79            ::std::mem::size_of::<$crate::libc::c_int>()
80        )
81    };
82}
83
84/// Generate an ioctl request code for a command that reads.
85///
86/// This is equivalent to the `_IOR()` macro exposed by the C ioctl API.
87///
88/// You should only use this macro directly if the `ioctl` you're working
89/// with is "bad" and you cannot use `ioctl_read!()` directly.
90///
91/// The read/write direction is relative to userland, so this
92/// command would be userland is reading and the kernel is
93/// writing.
94#[macro_export(local_inner_macros)]
95macro_rules! request_code_read {
96    ($g:expr, $n:expr, $len:expr) => {
97        ioc!($crate::sys::ioctl::OUT, $g, $n, $len)
98    };
99}
100
101/// Generate an ioctl request code for a command that writes.
102///
103/// This is equivalent to the `_IOW()` macro exposed by the C ioctl API.
104///
105/// You should only use this macro directly if the `ioctl` you're working
106/// with is "bad" and you cannot use `ioctl_write!()` directly.
107///
108/// The read/write direction is relative to userland, so this
109/// command would be userland is writing and the kernel is
110/// reading.
111#[macro_export(local_inner_macros)]
112macro_rules! request_code_write {
113    ($g:expr, $n:expr, $len:expr) => {
114        ioc!($crate::sys::ioctl::IN, $g, $n, $len)
115    };
116}
117
118/// Generate an ioctl request code for a command that reads and writes.
119///
120/// This is equivalent to the `_IOWR()` 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_readwrite!()` directly.
124#[macro_export(local_inner_macros)]
125macro_rules! request_code_readwrite {
126    ($g:expr, $n:expr, $len:expr) => {
127        ioc!($crate::sys::ioctl::INOUT, $g, $n, $len)
128    };
129}
130