• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Provide helpers for making ioctl system calls.
2 //!
3 //! This library is pretty low-level and messy. `ioctl` is not fun.
4 //!
5 //! What is an `ioctl`?
6 //! ===================
7 //!
8 //! The `ioctl` syscall is the grab-bag syscall on POSIX systems. Don't want to add a new
9 //! syscall? Make it an `ioctl`! `ioctl` refers to both the syscall, and the commands that can be
10 //! sent with it. `ioctl` stands for "IO control", and the commands are always sent to a file
11 //! descriptor.
12 //!
13 //! It is common to see `ioctl`s used for the following purposes:
14 //!
15 //!   * Provide read/write access to out-of-band data related to a device such as configuration
16 //!     (for instance, setting serial port options)
17 //!   * Provide a mechanism for performing full-duplex data transfers (for instance, xfer on SPI
18 //!     devices).
19 //!   * Provide access to control functions on a device (for example, on Linux you can send
20 //!     commands like pause, resume, and eject to the CDROM device.
21 //!   * Do whatever else the device driver creator thought made most sense.
22 //!
23 //! `ioctl`s are synchronous system calls and are similar to read and write calls in that regard.
24 //! They operate on file descriptors and have an identifier that specifies what the ioctl is.
25 //! Additionally they may read or write data and therefore need to pass along a data pointer.
26 //! Besides the semantics of the ioctls being confusing, the generation of this identifer can also
27 //! be difficult.
28 //!
29 //! Historically `ioctl` numbers were arbitrary hard-coded values. In Linux (before 2.6) and some
30 //! unices this has changed to a more-ordered system where the ioctl numbers are partitioned into
31 //! subcomponents (For linux this is documented in
32 //! [`Documentation/ioctl/ioctl-number.rst`](https://elixir.bootlin.com/linux/latest/source/Documentation/userspace-api/ioctl/ioctl-number.rst)):
33 //!
34 //!   * Number: The actual ioctl ID
35 //!   * Type: A grouping of ioctls for a common purpose or driver
36 //!   * Size: The size in bytes of the data that will be transferred
37 //!   * Direction: Whether there is any data and if it's read, write, or both
38 //!
39 //! Newer drivers should not generate complete integer identifiers for their `ioctl`s instead
40 //! preferring to use the 4 components above to generate the final ioctl identifier. Because of
41 //! how old `ioctl`s are, however, there are many hard-coded `ioctl` identifiers. These are
42 //! commonly referred to as "bad" in `ioctl` documentation.
43 //!
44 //! Defining `ioctl`s
45 //! =================
46 //!
47 //! This library provides several `ioctl_*!` macros for binding `ioctl`s. These generate public
48 //! unsafe functions that can then be used for calling the ioctl. This macro has a few different
49 //! ways it can be used depending on the specific ioctl you're working with.
50 //!
51 //! A simple `ioctl` is `SPI_IOC_RD_MODE`. This ioctl works with the SPI interface on Linux. This
52 //! specific `ioctl` reads the mode of the SPI device as a `u8`. It's declared in
53 //! `/include/uapi/linux/spi/spidev.h` as `_IOR(SPI_IOC_MAGIC, 1, __u8)`. Since it uses the `_IOR`
54 //! macro, we know it's a `read` ioctl and can use the `ioctl_read!` macro as follows:
55 //!
56 //! ```
57 //! # #[macro_use] extern crate nix;
58 //! const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
59 //! const SPI_IOC_TYPE_MODE: u8 = 1;
60 //! ioctl_read!(spi_read_mode, SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, u8);
61 //! # fn main() {}
62 //! ```
63 //!
64 //! This generates the function:
65 //!
66 //! ```
67 //! # #[macro_use] extern crate nix;
68 //! # use std::mem;
69 //! # use nix::{libc, Result};
70 //! # use nix::errno::Errno;
71 //! # use nix::libc::c_int as c_int;
72 //! # const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
73 //! # const SPI_IOC_TYPE_MODE: u8 = 1;
74 //! pub unsafe fn spi_read_mode(fd: c_int, data: *mut u8) -> Result<c_int> {
75 //!     let res = libc::ioctl(fd, request_code_read!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, mem::size_of::<u8>()), data);
76 //!     Errno::result(res)
77 //! }
78 //! # fn main() {}
79 //! ```
80 //!
81 //! The return value for the wrapper functions generated by the `ioctl_*!` macros are `nix::Error`s.
82 //! These are generated by assuming the return value of the ioctl is `-1` on error and everything
83 //! else is a valid return value. If this is not the case, `Result::map` can be used to map some
84 //! of the range of "good" values (-Inf..-2, 0..Inf) into a smaller range in a helper function.
85 //!
86 //! Writing `ioctl`s generally use pointers as their data source and these should use the
87 //! `ioctl_write_ptr!`. But in some cases an `int` is passed directly. For these `ioctl`s use the
88 //! `ioctl_write_int!` macro. This variant does not take a type as the last argument:
89 //!
90 //! ```
91 //! # #[macro_use] extern crate nix;
92 //! const HCI_IOC_MAGIC: u8 = b'k';
93 //! const HCI_IOC_HCIDEVUP: u8 = 1;
94 //! ioctl_write_int!(hci_dev_up, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP);
95 //! # fn main() {}
96 //! ```
97 //!
98 //! Some `ioctl`s don't transfer any data, and those should use `ioctl_none!`. This macro
99 //! doesn't take a type and so it is declared similar to the `write_int` variant shown above.
100 //!
101 //! The mode for a given `ioctl` should be clear from the documentation if it has good
102 //! documentation. Otherwise it will be clear based on the macro used to generate the `ioctl`
103 //! number where `_IO`, `_IOR`, `_IOW`, and `_IOWR` map to "none", "read", "write_*", and "readwrite"
104 //! respectively. To determine the specific `write_` variant to use you'll need to find
105 //! what the argument type is supposed to be. If it's an `int`, then `write_int` should be used,
106 //! otherwise it should be a pointer and `write_ptr` should be used. On Linux the
107 //! [`ioctl_list` man page](https://man7.org/linux/man-pages/man2/ioctl_list.2.html) describes a
108 //! large number of `ioctl`s and describes their argument data type.
109 //!
110 //! Using "bad" `ioctl`s
111 //! --------------------
112 //!
113 //! As mentioned earlier, there are many old `ioctl`s that do not use the newer method of
114 //! generating `ioctl` numbers and instead use hardcoded values. These can be used with the
115 //! `ioctl_*_bad!` macros. This naming comes from the Linux kernel which refers to these
116 //! `ioctl`s as "bad". These are a different variant as they bypass calling the macro that generates
117 //! the ioctl number and instead use the defined value directly.
118 //!
119 //! For example the `TCGETS` `ioctl` reads a `termios` data structure for a given file descriptor.
120 //! It's defined as `0x5401` in `ioctls.h` on Linux and can be implemented as:
121 //!
122 //! ```
123 //! # #[macro_use] extern crate nix;
124 //! # #[cfg(any(target_os = "android", target_os = "linux"))]
125 //! # use nix::libc::TCGETS as TCGETS;
126 //! # #[cfg(any(target_os = "android", target_os = "linux"))]
127 //! # use nix::libc::termios as termios;
128 //! # #[cfg(any(target_os = "android", target_os = "linux"))]
129 //! ioctl_read_bad!(tcgets, TCGETS, termios);
130 //! # fn main() {}
131 //! ```
132 //!
133 //! The generated function has the same form as that generated by `ioctl_read!`:
134 //!
135 //! ```text
136 //! pub unsafe fn tcgets(fd: c_int, data: *mut termios) -> Result<c_int>;
137 //! ```
138 //!
139 //! Working with Arrays
140 //! -------------------
141 //!
142 //! Some `ioctl`s work with entire arrays of elements. These are supported by the `ioctl_*_buf`
143 //! family of macros: `ioctl_read_buf`, `ioctl_write_buf`, and `ioctl_readwrite_buf`. Note that
144 //! there are no "bad" versions for working with buffers. The generated functions include a `len`
145 //! argument to specify the number of elements (where the type of each element is specified in the
146 //! macro).
147 //!
148 //! Again looking to the SPI `ioctl`s on Linux for an example, there is a `SPI_IOC_MESSAGE` `ioctl`
149 //! that queues up multiple SPI messages by writing an entire array of `spi_ioc_transfer` structs.
150 //! `linux/spi/spidev.h` defines a macro to calculate the `ioctl` number like:
151 //!
152 //! ```C
153 //! #define SPI_IOC_MAGIC 'k'
154 //! #define SPI_MSGSIZE(N) ...
155 //! #define SPI_IOC_MESSAGE(N) _IOW(SPI_IOC_MAGIC, 0, char[SPI_MSGSIZE(N)])
156 //! ```
157 //!
158 //! The `SPI_MSGSIZE(N)` calculation is already handled by the `ioctl_*!` macros, so all that's
159 //! needed to define this `ioctl` is:
160 //!
161 //! ```
162 //! # #[macro_use] extern crate nix;
163 //! const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
164 //! const SPI_IOC_TYPE_MESSAGE: u8 = 0;
165 //! # pub struct spi_ioc_transfer(u64);
166 //! ioctl_write_buf!(spi_transfer, SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, spi_ioc_transfer);
167 //! # fn main() {}
168 //! ```
169 //!
170 //! This generates a function like:
171 //!
172 //! ```
173 //! # #[macro_use] extern crate nix;
174 //! # use std::mem;
175 //! # use nix::{libc, Result};
176 //! # use nix::errno::Errno;
177 //! # use nix::libc::c_int as c_int;
178 //! # const SPI_IOC_MAGIC: u8 = b'k';
179 //! # const SPI_IOC_TYPE_MESSAGE: u8 = 0;
180 //! # pub struct spi_ioc_transfer(u64);
181 //! pub unsafe fn spi_message(fd: c_int, data: &mut [spi_ioc_transfer]) -> Result<c_int> {
182 //!     let res = libc::ioctl(fd,
183 //!                           request_code_write!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, data.len() * mem::size_of::<spi_ioc_transfer>()),
184 //!                           data);
185 //!     Errno::result(res)
186 //! }
187 //! # fn main() {}
188 //! ```
189 //!
190 //! Finding `ioctl` Documentation
191 //! -----------------------------
192 //!
193 //! For Linux, look at your system's headers. For example, `/usr/include/linux/input.h` has a lot
194 //! of lines defining macros which use `_IO`, `_IOR`, `_IOW`, `_IOC`, and `_IOWR`. Some `ioctl`s are
195 //! documented directly in the headers defining their constants, but others have more extensive
196 //! documentation in man pages (like termios' `ioctl`s which are in `tty_ioctl(4)`).
197 //!
198 //! Documenting the Generated Functions
199 //! ===================================
200 //!
201 //! In many cases, users will wish for the functions generated by the `ioctl`
202 //! macro to be public and documented. For this reason, the generated functions
203 //! are public by default. If you wish to hide the ioctl, you will need to put
204 //! them in a private module.
205 //!
206 //! For documentation, it is possible to use doc comments inside the `ioctl_*!` macros. Here is an
207 //! example :
208 //!
209 //! ```
210 //! # #[macro_use] extern crate nix;
211 //! # use nix::libc::c_int;
212 //! ioctl_read! {
213 //!     /// Make the given terminal the controlling terminal of the calling process. The calling
214 //!     /// process must be a session leader and not have a controlling terminal already. If the
215 //!     /// terminal is already the controlling terminal of a different session group then the
216 //!     /// ioctl will fail with **EPERM**, unless the caller is root (more precisely: has the
217 //!     /// **CAP_SYS_ADMIN** capability) and arg equals 1, in which case the terminal is stolen
218 //!     /// and all processes that had it as controlling terminal lose it.
219 //!     tiocsctty, b't', 19, c_int
220 //! }
221 //!
222 //! # fn main() {}
223 //! ```
224 use cfg_if::cfg_if;
225 
226 #[cfg(any(target_os = "android", target_os = "linux", target_os = "redox"))]
227 #[macro_use]
228 mod linux;
229 
230 #[cfg(any(
231     target_os = "android",
232     target_os = "linux",
233     target_os = "redox"
234 ))]
235 pub use self::linux::*;
236 
237 #[cfg(any(
238     target_os = "dragonfly",
239     target_os = "freebsd",
240     target_os = "illumos",
241     target_os = "ios",
242     target_os = "macos",
243     target_os = "netbsd",
244     target_os = "haiku",
245     target_os = "openbsd"
246 ))]
247 #[macro_use]
248 mod bsd;
249 
250 #[cfg(any(
251     target_os = "dragonfly",
252     target_os = "freebsd",
253     target_os = "illumos",
254     target_os = "ios",
255     target_os = "macos",
256     target_os = "netbsd",
257     target_os = "haiku",
258     target_os = "openbsd"
259 ))]
260 pub use self::bsd::*;
261 
262 /// Convert raw ioctl return value to a Nix result
263 #[macro_export]
264 #[doc(hidden)]
265 macro_rules! convert_ioctl_res {
266     ($w:expr) => {{
267         $crate::errno::Errno::result($w)
268     }};
269 }
270 
271 /// Generates a wrapper function for an ioctl that passes no data to the kernel.
272 ///
273 /// The arguments to this macro are:
274 ///
275 /// * The function name
276 /// * The ioctl identifier
277 /// * The ioctl sequence number
278 ///
279 /// The generated function has the following signature:
280 ///
281 /// ```rust,ignore
282 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result<libc::c_int>
283 /// ```
284 ///
285 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
286 ///
287 /// # Example
288 ///
289 /// The `videodev2` driver on Linux defines the `log_status` `ioctl` as:
290 ///
291 /// ```C
292 /// #define VIDIOC_LOG_STATUS         _IO('V', 70)
293 /// ```
294 ///
295 /// This can be implemented in Rust like:
296 ///
297 /// ```no_run
298 /// # #[macro_use] extern crate nix;
299 /// ioctl_none!(log_status, b'V', 70);
300 /// fn main() {}
301 /// ```
302 #[macro_export(local_inner_macros)]
303 macro_rules! ioctl_none {
304     ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => (
305         $(#[$attr])*
306         pub unsafe fn $name(fd: $crate::libc::c_int)
307                             -> $crate::Result<$crate::libc::c_int> {
308             convert_ioctl_res!($crate::libc::ioctl(fd, request_code_none!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type))
309         }
310     )
311 }
312 
313 /// Generates a wrapper function for a "bad" ioctl that passes no data to the kernel.
314 ///
315 /// The arguments to this macro are:
316 ///
317 /// * The function name
318 /// * The ioctl request code
319 ///
320 /// The generated function has the following signature:
321 ///
322 /// ```rust,ignore
323 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result<libc::c_int>
324 /// ```
325 ///
326 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
327 ///
328 /// # Example
329 ///
330 /// ```no_run
331 /// # #[macro_use] extern crate nix;
332 /// # use libc::TIOCNXCL;
333 /// # use std::fs::File;
334 /// # use std::os::unix::io::AsRawFd;
335 /// ioctl_none_bad!(tiocnxcl, TIOCNXCL);
336 /// fn main() {
337 ///     let file = File::open("/dev/ttyUSB0").unwrap();
338 ///     unsafe { tiocnxcl(file.as_raw_fd()) }.unwrap();
339 /// }
340 /// ```
341 // TODO: add an example using request_code_*!()
342 #[macro_export(local_inner_macros)]
343 macro_rules! ioctl_none_bad {
344     ($(#[$attr:meta])* $name:ident, $nr:expr) => (
345         $(#[$attr])*
346         pub unsafe fn $name(fd: $crate::libc::c_int)
347                             -> $crate::Result<$crate::libc::c_int> {
348             convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type))
349         }
350     )
351 }
352 
353 /// Generates a wrapper function for an ioctl that reads data from the kernel.
354 ///
355 /// The arguments to this macro are:
356 ///
357 /// * The function name
358 /// * The ioctl identifier
359 /// * The ioctl sequence number
360 /// * The data type passed by this ioctl
361 ///
362 /// The generated function has the following signature:
363 ///
364 /// ```rust,ignore
365 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
366 /// ```
367 ///
368 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
369 ///
370 /// # Example
371 ///
372 /// ```
373 /// # #[macro_use] extern crate nix;
374 /// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
375 /// const SPI_IOC_TYPE_MODE: u8 = 1;
376 /// ioctl_read!(spi_read_mode, SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, u8);
377 /// # fn main() {}
378 /// ```
379 #[macro_export(local_inner_macros)]
380 macro_rules! ioctl_read {
381     ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
382         $(#[$attr])*
383         pub unsafe fn $name(fd: $crate::libc::c_int,
384                             data: *mut $ty)
385                             -> $crate::Result<$crate::libc::c_int> {
386             convert_ioctl_res!($crate::libc::ioctl(fd, request_code_read!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
387         }
388     )
389 }
390 
391 /// Generates a wrapper function for a "bad" ioctl that reads data from the kernel.
392 ///
393 /// The arguments to this macro are:
394 ///
395 /// * The function name
396 /// * The ioctl request code
397 /// * The data type passed by this ioctl
398 ///
399 /// The generated function has the following signature:
400 ///
401 /// ```rust,ignore
402 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
403 /// ```
404 ///
405 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
406 ///
407 /// # Example
408 ///
409 /// ```
410 /// # #[macro_use] extern crate nix;
411 /// # #[cfg(any(target_os = "android", target_os = "linux"))]
412 /// ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios);
413 /// # fn main() {}
414 /// ```
415 #[macro_export(local_inner_macros)]
416 macro_rules! ioctl_read_bad {
417     ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
418         $(#[$attr])*
419         pub unsafe fn $name(fd: $crate::libc::c_int,
420                             data: *mut $ty)
421                             -> $crate::Result<$crate::libc::c_int> {
422             convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
423         }
424     )
425 }
426 
427 /// Generates a wrapper function for an ioctl that writes data through a pointer to the kernel.
428 ///
429 /// The arguments to this macro are:
430 ///
431 /// * The function name
432 /// * The ioctl identifier
433 /// * The ioctl sequence number
434 /// * The data type passed by this ioctl
435 ///
436 /// The generated function has the following signature:
437 ///
438 /// ```rust,ignore
439 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result<libc::c_int>
440 /// ```
441 ///
442 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
443 ///
444 /// # Example
445 ///
446 /// ```
447 /// # #[macro_use] extern crate nix;
448 /// # pub struct v4l2_audio {}
449 /// ioctl_write_ptr!(s_audio, b'V', 34, v4l2_audio);
450 /// # fn main() {}
451 /// ```
452 #[macro_export(local_inner_macros)]
453 macro_rules! ioctl_write_ptr {
454     ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
455         $(#[$attr])*
456         pub unsafe fn $name(fd: $crate::libc::c_int,
457                             data: *const $ty)
458                             -> $crate::Result<$crate::libc::c_int> {
459             convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
460         }
461     )
462 }
463 
464 /// Generates a wrapper function for a "bad" ioctl that writes data through a pointer to the kernel.
465 ///
466 /// The arguments to this macro are:
467 ///
468 /// * The function name
469 /// * The ioctl request code
470 /// * The data type passed by this ioctl
471 ///
472 /// The generated function has the following signature:
473 ///
474 /// ```rust,ignore
475 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result<libc::c_int>
476 /// ```
477 ///
478 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
479 ///
480 /// # Example
481 ///
482 /// ```
483 /// # #[macro_use] extern crate nix;
484 /// # #[cfg(any(target_os = "android", target_os = "linux"))]
485 /// ioctl_write_ptr_bad!(tcsets, libc::TCSETS, libc::termios);
486 /// # fn main() {}
487 /// ```
488 #[macro_export(local_inner_macros)]
489 macro_rules! ioctl_write_ptr_bad {
490     ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
491         $(#[$attr])*
492         pub unsafe fn $name(fd: $crate::libc::c_int,
493                             data: *const $ty)
494                             -> $crate::Result<$crate::libc::c_int> {
495             convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
496         }
497     )
498 }
499 
500 cfg_if! {
501     if #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] {
502         /// Generates a wrapper function for a ioctl that writes an integer to the kernel.
503         ///
504         /// The arguments to this macro are:
505         ///
506         /// * The function name
507         /// * The ioctl identifier
508         /// * The ioctl sequence number
509         ///
510         /// The generated function has the following signature:
511         ///
512         /// ```rust,ignore
513         /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int>
514         /// ```
515         ///
516         /// `nix::sys::ioctl::ioctl_param_type` depends on the OS:
517         /// *   BSD - `libc::c_int`
518         /// *   Linux - `libc::c_ulong`
519         ///
520         /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
521         ///
522         /// # Example
523         ///
524         /// ```
525         /// # #[macro_use] extern crate nix;
526         /// ioctl_write_int!(vt_activate, b'v', 4);
527         /// # fn main() {}
528         /// ```
529         #[macro_export(local_inner_macros)]
530         macro_rules! ioctl_write_int {
531             ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => (
532                 $(#[$attr])*
533                 pub unsafe fn $name(fd: $crate::libc::c_int,
534                                     data: $crate::sys::ioctl::ioctl_param_type)
535                                     -> $crate::Result<$crate::libc::c_int> {
536                     convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write_int!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type, data))
537                 }
538             )
539         }
540     } else {
541         /// Generates a wrapper function for a ioctl that writes an integer to the kernel.
542         ///
543         /// The arguments to this macro are:
544         ///
545         /// * The function name
546         /// * The ioctl identifier
547         /// * The ioctl sequence number
548         ///
549         /// The generated function has the following signature:
550         ///
551         /// ```rust,ignore
552         /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int>
553         /// ```
554         ///
555         /// `nix::sys::ioctl::ioctl_param_type` depends on the OS:
556         /// *   BSD - `libc::c_int`
557         /// *   Linux - `libc::c_ulong`
558         ///
559         /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
560         ///
561         /// # Example
562         ///
563         /// ```
564         /// # #[macro_use] extern crate nix;
565         /// const HCI_IOC_MAGIC: u8 = b'k';
566         /// const HCI_IOC_HCIDEVUP: u8 = 1;
567         /// ioctl_write_int!(hci_dev_up, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP);
568         /// # fn main() {}
569         /// ```
570         #[macro_export(local_inner_macros)]
571         macro_rules! ioctl_write_int {
572             ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => (
573                 $(#[$attr])*
574                 pub unsafe fn $name(fd: $crate::libc::c_int,
575                                     data: $crate::sys::ioctl::ioctl_param_type)
576                                     -> $crate::Result<$crate::libc::c_int> {
577                     convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, ::std::mem::size_of::<$crate::libc::c_int>()) as $crate::sys::ioctl::ioctl_num_type, data))
578                 }
579             )
580         }
581     }
582 }
583 
584 /// Generates a wrapper function for a "bad" ioctl that writes an integer to the kernel.
585 ///
586 /// The arguments to this macro are:
587 ///
588 /// * The function name
589 /// * The ioctl request code
590 ///
591 /// The generated function has the following signature:
592 ///
593 /// ```rust,ignore
594 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: libc::c_int) -> Result<libc::c_int>
595 /// ```
596 ///
597 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
598 ///
599 /// # Examples
600 ///
601 /// ```
602 /// # #[macro_use] extern crate nix;
603 /// # #[cfg(any(target_os = "android", target_os = "linux"))]
604 /// ioctl_write_int_bad!(tcsbrk, libc::TCSBRK);
605 /// # fn main() {}
606 /// ```
607 ///
608 /// ```rust
609 /// # #[macro_use] extern crate nix;
610 /// const KVMIO: u8 = 0xAE;
611 /// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03));
612 /// # fn main() {}
613 /// ```
614 #[macro_export(local_inner_macros)]
615 macro_rules! ioctl_write_int_bad {
616     ($(#[$attr:meta])* $name:ident, $nr:expr) => (
617         $(#[$attr])*
618         pub unsafe fn $name(fd: $crate::libc::c_int,
619                             data: $crate::libc::c_int)
620                             -> $crate::Result<$crate::libc::c_int> {
621             convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
622         }
623     )
624 }
625 
626 /// Generates a wrapper function for an ioctl that reads and writes data to the kernel.
627 ///
628 /// The arguments to this macro are:
629 ///
630 /// * The function name
631 /// * The ioctl identifier
632 /// * The ioctl sequence number
633 /// * The data type passed by this ioctl
634 ///
635 /// The generated function has the following signature:
636 ///
637 /// ```rust,ignore
638 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
639 /// ```
640 ///
641 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
642 ///
643 /// # Example
644 ///
645 /// ```
646 /// # #[macro_use] extern crate nix;
647 /// # pub struct v4l2_audio {}
648 /// ioctl_readwrite!(enum_audio, b'V', 65, v4l2_audio);
649 /// # fn main() {}
650 /// ```
651 #[macro_export(local_inner_macros)]
652 macro_rules! ioctl_readwrite {
653     ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
654         $(#[$attr])*
655         pub unsafe fn $name(fd: $crate::libc::c_int,
656                             data: *mut $ty)
657                             -> $crate::Result<$crate::libc::c_int> {
658             convert_ioctl_res!($crate::libc::ioctl(fd, request_code_readwrite!($ioty, $nr, ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
659         }
660     )
661 }
662 
663 /// Generates a wrapper function for a "bad" ioctl that reads and writes data to the kernel.
664 ///
665 /// The arguments to this macro are:
666 ///
667 /// * The function name
668 /// * The ioctl request code
669 /// * The data type passed by this ioctl
670 ///
671 /// The generated function has the following signature:
672 ///
673 /// ```rust,ignore
674 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
675 /// ```
676 ///
677 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
678 // TODO: Find an example for ioctl_readwrite_bad
679 #[macro_export(local_inner_macros)]
680 macro_rules! ioctl_readwrite_bad {
681     ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
682         $(#[$attr])*
683         pub unsafe fn $name(fd: $crate::libc::c_int,
684                             data: *mut $ty)
685                             -> $crate::Result<$crate::libc::c_int> {
686             convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
687         }
688     )
689 }
690 
691 /// Generates a wrapper function for an ioctl that reads an array of elements from the kernel.
692 ///
693 /// The arguments to this macro are:
694 ///
695 /// * The function name
696 /// * The ioctl identifier
697 /// * The ioctl sequence number
698 /// * The data type passed by this ioctl
699 ///
700 /// The generated function has the following signature:
701 ///
702 /// ```rust,ignore
703 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int>
704 /// ```
705 ///
706 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
707 // TODO: Find an example for ioctl_read_buf
708 #[macro_export(local_inner_macros)]
709 macro_rules! ioctl_read_buf {
710     ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
711         $(#[$attr])*
712         pub unsafe fn $name(fd: $crate::libc::c_int,
713                             data: &mut [$ty])
714                             -> $crate::Result<$crate::libc::c_int> {
715             convert_ioctl_res!($crate::libc::ioctl(fd, request_code_read!($ioty, $nr, data.len() * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
716         }
717     )
718 }
719 
720 /// Generates a wrapper function for an ioctl that writes an array of elements to the kernel.
721 ///
722 /// The arguments to this macro are:
723 ///
724 /// * The function name
725 /// * The ioctl identifier
726 /// * The ioctl sequence number
727 /// * The data type passed by this ioctl
728 ///
729 /// The generated function has the following signature:
730 ///
731 /// ```rust,ignore
732 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &[DATA_TYPE]) -> Result<libc::c_int>
733 /// ```
734 ///
735 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
736 ///
737 /// # Examples
738 ///
739 /// ```
740 /// # #[macro_use] extern crate nix;
741 /// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
742 /// const SPI_IOC_TYPE_MESSAGE: u8 = 0;
743 /// # pub struct spi_ioc_transfer(u64);
744 /// ioctl_write_buf!(spi_transfer, SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, spi_ioc_transfer);
745 /// # fn main() {}
746 /// ```
747 #[macro_export(local_inner_macros)]
748 macro_rules! ioctl_write_buf {
749     ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
750         $(#[$attr])*
751         pub unsafe fn $name(fd: $crate::libc::c_int,
752                             data: &[$ty])
753                             -> $crate::Result<$crate::libc::c_int> {
754             convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, data.len() * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
755         }
756     )
757 }
758 
759 /// Generates a wrapper function for an ioctl that reads and writes an array of elements to the kernel.
760 ///
761 /// The arguments to this macro are:
762 ///
763 /// * The function name
764 /// * The ioctl identifier
765 /// * The ioctl sequence number
766 /// * The data type passed by this ioctl
767 ///
768 /// The generated function has the following signature:
769 ///
770 /// ```rust,ignore
771 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int>
772 /// ```
773 ///
774 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
775 // TODO: Find an example for readwrite_buf
776 #[macro_export(local_inner_macros)]
777 macro_rules! ioctl_readwrite_buf {
778     ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
779         $(#[$attr])*
780         pub unsafe fn $name(fd: $crate::libc::c_int,
781                             data: &mut [$ty])
782                             -> $crate::Result<$crate::libc::c_int> {
783             convert_ioctl_res!($crate::libc::ioctl(fd, request_code_readwrite!($ioty, $nr, data.len() * ::std::mem::size_of::<$ty>()) as $crate::sys::ioctl::ioctl_num_type, data))
784         }
785     )
786 }
787