• 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(target_os = "android", target_os = "linux", target_os = "redox"))]
231 pub use self::linux::*;
232 
233 #[cfg(any(target_os = "dragonfly",
234           target_os = "freebsd",
235           target_os = "illumos",
236           target_os = "ios",
237           target_os = "macos",
238           target_os = "netbsd",
239           target_os = "openbsd"))]
240 #[macro_use]
241 mod bsd;
242 
243 #[cfg(any(target_os = "dragonfly",
244           target_os = "freebsd",
245           target_os = "illumos",
246           target_os = "ios",
247           target_os = "macos",
248           target_os = "netbsd",
249           target_os = "openbsd"))]
250 pub use self::bsd::*;
251 
252 /// Convert raw ioctl return value to a Nix result
253 #[macro_export]
254 #[doc(hidden)]
255 macro_rules! convert_ioctl_res {
256     ($w:expr) => (
257         {
258             $crate::errno::Errno::result($w)
259         }
260     );
261 }
262 
263 /// Generates a wrapper function for an ioctl that passes no data to the kernel.
264 ///
265 /// The arguments to this macro are:
266 ///
267 /// * The function name
268 /// * The ioctl identifier
269 /// * The ioctl sequence number
270 ///
271 /// The generated function has the following signature:
272 ///
273 /// ```rust,ignore
274 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result<libc::c_int>
275 /// ```
276 ///
277 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
278 ///
279 /// # Example
280 ///
281 /// The `videodev2` driver on Linux defines the `log_status` `ioctl` as:
282 ///
283 /// ```C
284 /// #define VIDIOC_LOG_STATUS         _IO('V', 70)
285 /// ```
286 ///
287 /// This can be implemented in Rust like:
288 ///
289 /// ```no_run
290 /// # #[macro_use] extern crate nix;
291 /// ioctl_none!(log_status, b'V', 70);
292 /// fn main() {}
293 /// ```
294 #[macro_export(local_inner_macros)]
295 macro_rules! ioctl_none {
296     ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => (
297         $(#[$attr])*
298         pub unsafe fn $name(fd: $crate::libc::c_int)
299                             -> $crate::Result<$crate::libc::c_int> {
300             convert_ioctl_res!($crate::libc::ioctl(fd, request_code_none!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type))
301         }
302     )
303 }
304 
305 /// Generates a wrapper function for a "bad" ioctl that passes no data to the kernel.
306 ///
307 /// The arguments to this macro are:
308 ///
309 /// * The function name
310 /// * The ioctl request code
311 ///
312 /// The generated function has the following signature:
313 ///
314 /// ```rust,ignore
315 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result<libc::c_int>
316 /// ```
317 ///
318 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
319 ///
320 /// # Example
321 ///
322 /// ```no_run
323 /// # #[macro_use] extern crate nix;
324 /// # use libc::TIOCNXCL;
325 /// # use std::fs::File;
326 /// # use std::os::unix::io::AsRawFd;
327 /// ioctl_none_bad!(tiocnxcl, TIOCNXCL);
328 /// fn main() {
329 ///     let file = File::open("/dev/ttyUSB0").unwrap();
330 ///     unsafe { tiocnxcl(file.as_raw_fd()) }.unwrap();
331 /// }
332 /// ```
333 // TODO: add an example using request_code_*!()
334 #[macro_export(local_inner_macros)]
335 macro_rules! ioctl_none_bad {
336     ($(#[$attr:meta])* $name:ident, $nr:expr) => (
337         $(#[$attr])*
338         pub unsafe fn $name(fd: $crate::libc::c_int)
339                             -> $crate::Result<$crate::libc::c_int> {
340             convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type))
341         }
342     )
343 }
344 
345 /// Generates a wrapper function for an ioctl that reads data from the kernel.
346 ///
347 /// The arguments to this macro are:
348 ///
349 /// * The function name
350 /// * The ioctl identifier
351 /// * The ioctl sequence number
352 /// * The data type passed by this ioctl
353 ///
354 /// The generated function has the following signature:
355 ///
356 /// ```rust,ignore
357 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
358 /// ```
359 ///
360 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
361 ///
362 /// # Example
363 ///
364 /// ```
365 /// # #[macro_use] extern crate nix;
366 /// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
367 /// const SPI_IOC_TYPE_MODE: u8 = 1;
368 /// ioctl_read!(spi_read_mode, SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, u8);
369 /// # fn main() {}
370 /// ```
371 #[macro_export(local_inner_macros)]
372 macro_rules! ioctl_read {
373     ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
374         $(#[$attr])*
375         pub unsafe fn $name(fd: $crate::libc::c_int,
376                             data: *mut $ty)
377                             -> $crate::Result<$crate::libc::c_int> {
378             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))
379         }
380     )
381 }
382 
383 /// Generates a wrapper function for a "bad" ioctl that reads data from the kernel.
384 ///
385 /// The arguments to this macro are:
386 ///
387 /// * The function name
388 /// * The ioctl request code
389 /// * The data type passed by this ioctl
390 ///
391 /// The generated function has the following signature:
392 ///
393 /// ```rust,ignore
394 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
395 /// ```
396 ///
397 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
398 ///
399 /// # Example
400 ///
401 /// ```
402 /// # #[macro_use] extern crate nix;
403 /// # #[cfg(any(target_os = "android", target_os = "linux"))]
404 /// ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios);
405 /// # fn main() {}
406 /// ```
407 #[macro_export(local_inner_macros)]
408 macro_rules! ioctl_read_bad {
409     ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
410         $(#[$attr])*
411         pub unsafe fn $name(fd: $crate::libc::c_int,
412                             data: *mut $ty)
413                             -> $crate::Result<$crate::libc::c_int> {
414             convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
415         }
416     )
417 }
418 
419 /// Generates a wrapper function for an ioctl that writes data through a pointer to the kernel.
420 ///
421 /// The arguments to this macro are:
422 ///
423 /// * The function name
424 /// * The ioctl identifier
425 /// * The ioctl sequence number
426 /// * The data type passed by this ioctl
427 ///
428 /// The generated function has the following signature:
429 ///
430 /// ```rust,ignore
431 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result<libc::c_int>
432 /// ```
433 ///
434 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
435 ///
436 /// # Example
437 ///
438 /// ```
439 /// # #[macro_use] extern crate nix;
440 /// # pub struct v4l2_audio {}
441 /// ioctl_write_ptr!(s_audio, b'V', 34, v4l2_audio);
442 /// # fn main() {}
443 /// ```
444 #[macro_export(local_inner_macros)]
445 macro_rules! ioctl_write_ptr {
446     ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
447         $(#[$attr])*
448         pub unsafe fn $name(fd: $crate::libc::c_int,
449                             data: *const $ty)
450                             -> $crate::Result<$crate::libc::c_int> {
451             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))
452         }
453     )
454 }
455 
456 /// Generates a wrapper function for a "bad" ioctl that writes data through a pointer to the kernel.
457 ///
458 /// The arguments to this macro are:
459 ///
460 /// * The function name
461 /// * The ioctl request code
462 /// * The data type passed by this ioctl
463 ///
464 /// The generated function has the following signature:
465 ///
466 /// ```rust,ignore
467 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result<libc::c_int>
468 /// ```
469 ///
470 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
471 ///
472 /// # Example
473 ///
474 /// ```
475 /// # #[macro_use] extern crate nix;
476 /// # #[cfg(any(target_os = "android", target_os = "linux"))]
477 /// ioctl_write_ptr_bad!(tcsets, libc::TCSETS, libc::termios);
478 /// # fn main() {}
479 /// ```
480 #[macro_export(local_inner_macros)]
481 macro_rules! ioctl_write_ptr_bad {
482     ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
483         $(#[$attr])*
484         pub unsafe fn $name(fd: $crate::libc::c_int,
485                             data: *const $ty)
486                             -> $crate::Result<$crate::libc::c_int> {
487             convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
488         }
489     )
490 }
491 
492 cfg_if!{
493     if #[cfg(any(target_os = "dragonfly", target_os = "freebsd"))] {
494         /// Generates a wrapper function for a ioctl that writes an integer to the kernel.
495         ///
496         /// The arguments to this macro are:
497         ///
498         /// * The function name
499         /// * The ioctl identifier
500         /// * The ioctl sequence number
501         ///
502         /// The generated function has the following signature:
503         ///
504         /// ```rust,ignore
505         /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int>
506         /// ```
507         ///
508         /// `nix::sys::ioctl::ioctl_param_type` depends on the OS:
509         /// *   BSD - `libc::c_int`
510         /// *   Linux - `libc::c_ulong`
511         ///
512         /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
513         ///
514         /// # Example
515         ///
516         /// ```
517         /// # #[macro_use] extern crate nix;
518         /// ioctl_write_int!(vt_activate, b'v', 4);
519         /// # fn main() {}
520         /// ```
521         #[macro_export(local_inner_macros)]
522         macro_rules! ioctl_write_int {
523             ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => (
524                 $(#[$attr])*
525                 pub unsafe fn $name(fd: $crate::libc::c_int,
526                                     data: $crate::sys::ioctl::ioctl_param_type)
527                                     -> $crate::Result<$crate::libc::c_int> {
528                     convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write_int!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type, data))
529                 }
530             )
531         }
532     } else {
533         /// Generates a wrapper function for a ioctl that writes an integer to the kernel.
534         ///
535         /// The arguments to this macro are:
536         ///
537         /// * The function name
538         /// * The ioctl identifier
539         /// * The ioctl sequence number
540         ///
541         /// The generated function has the following signature:
542         ///
543         /// ```rust,ignore
544         /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int>
545         /// ```
546         ///
547         /// `nix::sys::ioctl::ioctl_param_type` depends on the OS:
548         /// *   BSD - `libc::c_int`
549         /// *   Linux - `libc::c_ulong`
550         ///
551         /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
552         ///
553         /// # Example
554         ///
555         /// ```
556         /// # #[macro_use] extern crate nix;
557         /// const HCI_IOC_MAGIC: u8 = b'k';
558         /// const HCI_IOC_HCIDEVUP: u8 = 1;
559         /// ioctl_write_int!(hci_dev_up, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP);
560         /// # fn main() {}
561         /// ```
562         #[macro_export(local_inner_macros)]
563         macro_rules! ioctl_write_int {
564             ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => (
565                 $(#[$attr])*
566                 pub unsafe fn $name(fd: $crate::libc::c_int,
567                                     data: $crate::sys::ioctl::ioctl_param_type)
568                                     -> $crate::Result<$crate::libc::c_int> {
569                     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))
570                 }
571             )
572         }
573     }
574 }
575 
576 /// Generates a wrapper function for a "bad" ioctl that writes an integer to the kernel.
577 ///
578 /// The arguments to this macro are:
579 ///
580 /// * The function name
581 /// * The ioctl request code
582 ///
583 /// The generated function has the following signature:
584 ///
585 /// ```rust,ignore
586 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: libc::c_int) -> Result<libc::c_int>
587 /// ```
588 ///
589 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
590 ///
591 /// # Examples
592 ///
593 /// ```
594 /// # #[macro_use] extern crate nix;
595 /// # #[cfg(any(target_os = "android", target_os = "linux"))]
596 /// ioctl_write_int_bad!(tcsbrk, libc::TCSBRK);
597 /// # fn main() {}
598 /// ```
599 ///
600 /// ```rust
601 /// # #[macro_use] extern crate nix;
602 /// const KVMIO: u8 = 0xAE;
603 /// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03));
604 /// # fn main() {}
605 /// ```
606 #[macro_export(local_inner_macros)]
607 macro_rules! ioctl_write_int_bad {
608     ($(#[$attr:meta])* $name:ident, $nr:expr) => (
609         $(#[$attr])*
610         pub unsafe fn $name(fd: $crate::libc::c_int,
611                             data: $crate::libc::c_int)
612                             -> $crate::Result<$crate::libc::c_int> {
613             convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
614         }
615     )
616 }
617 
618 /// Generates a wrapper function for an ioctl that reads and writes data to the kernel.
619 ///
620 /// The arguments to this macro are:
621 ///
622 /// * The function name
623 /// * The ioctl identifier
624 /// * The ioctl sequence number
625 /// * The data type passed by this ioctl
626 ///
627 /// The generated function has the following signature:
628 ///
629 /// ```rust,ignore
630 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
631 /// ```
632 ///
633 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
634 ///
635 /// # Example
636 ///
637 /// ```
638 /// # #[macro_use] extern crate nix;
639 /// # pub struct v4l2_audio {}
640 /// ioctl_readwrite!(enum_audio, b'V', 65, v4l2_audio);
641 /// # fn main() {}
642 /// ```
643 #[macro_export(local_inner_macros)]
644 macro_rules! ioctl_readwrite {
645     ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
646         $(#[$attr])*
647         pub unsafe fn $name(fd: $crate::libc::c_int,
648                             data: *mut $ty)
649                             -> $crate::Result<$crate::libc::c_int> {
650             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))
651         }
652     )
653 }
654 
655 /// Generates a wrapper function for a "bad" ioctl that reads and writes data to the kernel.
656 ///
657 /// The arguments to this macro are:
658 ///
659 /// * The function name
660 /// * The ioctl request code
661 /// * The data type passed by this ioctl
662 ///
663 /// The generated function has the following signature:
664 ///
665 /// ```rust,ignore
666 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
667 /// ```
668 ///
669 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
670 // TODO: Find an example for ioctl_readwrite_bad
671 #[macro_export(local_inner_macros)]
672 macro_rules! ioctl_readwrite_bad {
673     ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
674         $(#[$attr])*
675         pub unsafe fn $name(fd: $crate::libc::c_int,
676                             data: *mut $ty)
677                             -> $crate::Result<$crate::libc::c_int> {
678             convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
679         }
680     )
681 }
682 
683 /// Generates a wrapper function for an ioctl that reads an array of elements from the kernel.
684 ///
685 /// The arguments to this macro are:
686 ///
687 /// * The function name
688 /// * The ioctl identifier
689 /// * The ioctl sequence number
690 /// * The data type passed by this ioctl
691 ///
692 /// The generated function has the following signature:
693 ///
694 /// ```rust,ignore
695 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int>
696 /// ```
697 ///
698 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
699 // TODO: Find an example for ioctl_read_buf
700 #[macro_export(local_inner_macros)]
701 macro_rules! ioctl_read_buf {
702     ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
703         $(#[$attr])*
704         pub unsafe fn $name(fd: $crate::libc::c_int,
705                             data: &mut [$ty])
706                             -> $crate::Result<$crate::libc::c_int> {
707             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))
708         }
709     )
710 }
711 
712 /// Generates a wrapper function for an ioctl that writes an array of elements to the kernel.
713 ///
714 /// The arguments to this macro are:
715 ///
716 /// * The function name
717 /// * The ioctl identifier
718 /// * The ioctl sequence number
719 /// * The data type passed by this ioctl
720 ///
721 /// The generated function has the following signature:
722 ///
723 /// ```rust,ignore
724 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &[DATA_TYPE]) -> Result<libc::c_int>
725 /// ```
726 ///
727 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
728 ///
729 /// # Examples
730 ///
731 /// ```
732 /// # #[macro_use] extern crate nix;
733 /// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
734 /// const SPI_IOC_TYPE_MESSAGE: u8 = 0;
735 /// # pub struct spi_ioc_transfer(u64);
736 /// ioctl_write_buf!(spi_transfer, SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, spi_ioc_transfer);
737 /// # fn main() {}
738 /// ```
739 #[macro_export(local_inner_macros)]
740 macro_rules! ioctl_write_buf {
741     ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
742         $(#[$attr])*
743         pub unsafe fn $name(fd: $crate::libc::c_int,
744                             data: &[$ty])
745                             -> $crate::Result<$crate::libc::c_int> {
746             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))
747         }
748     )
749 }
750 
751 /// Generates a wrapper function for an ioctl that reads and writes an array of elements to the kernel.
752 ///
753 /// The arguments to this macro are:
754 ///
755 /// * The function name
756 /// * The ioctl identifier
757 /// * The ioctl sequence number
758 /// * The data type passed by this ioctl
759 ///
760 /// The generated function has the following signature:
761 ///
762 /// ```rust,ignore
763 /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int>
764 /// ```
765 ///
766 /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
767 // TODO: Find an example for readwrite_buf
768 #[macro_export(local_inner_macros)]
769 macro_rules! ioctl_readwrite_buf {
770     ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
771         $(#[$attr])*
772         pub unsafe fn $name(fd: $crate::libc::c_int,
773                             data: &mut [$ty])
774                             -> $crate::Result<$crate::libc::c_int> {
775             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))
776         }
777     )
778 }
779