Skip to main content

nix/sys/ioctl/
mod.rs

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 = unsafe { 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(linux_android)]
125//! # use nix::libc::TCGETS as TCGETS;
126//! # #[cfg(linux_android)]
127//! # use nix::libc::termios as termios;
128//! # #[cfg(linux_android)]
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 = unsafe {
183//!         libc::ioctl(
184//!             fd,
185//!             request_code_write!(SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, data.len() * mem::size_of::<spi_ioc_transfer>()),
186//!             data
187//!         )
188//!     };
189//!     Errno::result(res)
190//! }
191//! # fn main() {}
192//! ```
193//!
194//! Finding `ioctl` Documentation
195//! -----------------------------
196//!
197//! For Linux, look at your system's headers. For example, `/usr/include/linux/input.h` has a lot
198//! of lines defining macros which use `_IO`, `_IOR`, `_IOW`, `_IOC`, and `_IOWR`. Some `ioctl`s are
199//! documented directly in the headers defining their constants, but others have more extensive
200//! documentation in man pages (like termios' `ioctl`s which are in `tty_ioctl(4)`).
201//!
202//! Documenting the Generated Functions
203//! ===================================
204//!
205//! In many cases, users will wish for the functions generated by the `ioctl`
206//! macro to be public and documented. For this reason, the generated functions
207//! are public by default. If you wish to hide the ioctl, you will need to put
208//! them in a private module.
209//!
210//! For documentation, it is possible to use doc comments inside the `ioctl_*!` macros. Here is an
211//! example :
212//!
213//! ```
214//! # #[macro_use] extern crate nix;
215//! # use nix::libc::c_int;
216//! ioctl_read! {
217//!     /// Make the given terminal the controlling terminal of the calling process. The calling
218//!     /// process must be a session leader and not have a controlling terminal already. If the
219//!     /// terminal is already the controlling terminal of a different session group then the
220//!     /// ioctl will fail with **EPERM**, unless the caller is root (more precisely: has the
221//!     /// **CAP_SYS_ADMIN** capability) and arg equals 1, in which case the terminal is stolen
222//!     /// and all processes that had it as controlling terminal lose it.
223//!     tiocsctty, b't', 19, c_int
224//! }
225//!
226//! # fn main() {}
227//! ```
228use cfg_if::cfg_if;
229
230#[cfg(any(
231    linux_android,
232    target_os = "fuchsia",
233    target_os = "redox",
234    target_os = "cygwin"
235))]
236#[macro_use]
237mod linux;
238
239#[cfg(any(
240    linux_android,
241    target_os = "fuchsia",
242    target_os = "redox",
243    target_os = "cygwin"
244))]
245pub use self::linux::*;
246
247#[cfg(any(bsd, solarish, target_os = "haiku",))]
248#[macro_use]
249mod bsd;
250
251#[cfg(any(bsd, solarish, target_os = "haiku",))]
252pub use self::bsd::*;
253
254/// Convert raw ioctl return value to a Nix result
255#[macro_export]
256#[doc(hidden)]
257macro_rules! convert_ioctl_res {
258    ($w:expr) => {{
259        $crate::errno::Errno::result($w)
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)]
295macro_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            unsafe {
301                convert_ioctl_res!($crate::libc::ioctl(fd, request_code_none!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type))
302            }
303        }
304    )
305}
306
307/// Generates a wrapper function for a "bad" ioctl that passes no data to the kernel.
308///
309/// The arguments to this macro are:
310///
311/// * The function name
312/// * The ioctl request code
313///
314/// The generated function has the following signature:
315///
316/// ```rust,ignore
317/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int) -> Result<libc::c_int>
318/// ```
319///
320/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
321///
322/// # Example
323///
324/// ```no_run
325/// # #[macro_use] extern crate nix;
326/// # use libc::TIOCNXCL;
327/// # use std::fs::File;
328/// # use std::os::unix::io::AsRawFd;
329/// ioctl_none_bad!(tiocnxcl, TIOCNXCL);
330/// fn main() {
331///     let file = File::open("/dev/ttyUSB0").unwrap();
332///     unsafe { tiocnxcl(file.as_raw_fd()) }.unwrap();
333/// }
334/// ```
335// TODO: add an example using request_code_*!()
336#[macro_export(local_inner_macros)]
337macro_rules! ioctl_none_bad {
338    ($(#[$attr:meta])* $name:ident, $nr:expr) => (
339        $(#[$attr])*
340        pub unsafe fn $name(fd: $crate::libc::c_int)
341                            -> $crate::Result<$crate::libc::c_int> {
342            unsafe {
343                convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type))
344            }
345        }
346    )
347}
348
349/// Generates a wrapper function for an ioctl that reads data from the kernel.
350///
351/// The arguments to this macro are:
352///
353/// * The function name
354/// * The ioctl identifier
355/// * The ioctl sequence number
356/// * The data type passed by this ioctl
357///
358/// The generated function has the following signature:
359///
360/// ```rust,ignore
361/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
362/// ```
363///
364/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
365///
366/// # Example
367///
368/// ```
369/// # #[macro_use] extern crate nix;
370/// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
371/// const SPI_IOC_TYPE_MODE: u8 = 1;
372/// ioctl_read!(spi_read_mode, SPI_IOC_MAGIC, SPI_IOC_TYPE_MODE, u8);
373/// # fn main() {}
374/// ```
375#[macro_export(local_inner_macros)]
376macro_rules! ioctl_read {
377    ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
378        $(#[$attr])*
379        pub unsafe fn $name(fd: $crate::libc::c_int,
380                            data: *mut $ty)
381                            -> $crate::Result<$crate::libc::c_int> {
382            unsafe {
383                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))
384            }
385        }
386    )
387}
388
389/// Generates a wrapper function for a "bad" ioctl that reads data from the kernel.
390///
391/// The arguments to this macro are:
392///
393/// * The function name
394/// * The ioctl request code
395/// * The data type passed by this ioctl
396///
397/// The generated function has the following signature:
398///
399/// ```rust,ignore
400/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
401/// ```
402///
403/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
404///
405/// # Example
406///
407/// ```
408/// # #[macro_use] extern crate nix;
409/// # #[cfg(linux_android)]
410/// ioctl_read_bad!(tcgets, libc::TCGETS, libc::termios);
411/// # fn main() {}
412/// ```
413#[macro_export(local_inner_macros)]
414macro_rules! ioctl_read_bad {
415    ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
416        $(#[$attr])*
417        pub unsafe fn $name(fd: $crate::libc::c_int,
418                            data: *mut $ty)
419                            -> $crate::Result<$crate::libc::c_int> {
420            unsafe {
421                convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
422            }
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)]
453macro_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            unsafe {
460                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))
461            }
462        }
463    )
464}
465
466/// Generates a wrapper function for a "bad" ioctl that writes data through a pointer to the kernel.
467///
468/// The arguments to this macro are:
469///
470/// * The function name
471/// * The ioctl request code
472/// * The data type passed by this ioctl
473///
474/// The generated function has the following signature:
475///
476/// ```rust,ignore
477/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *const DATA_TYPE) -> Result<libc::c_int>
478/// ```
479///
480/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
481///
482/// # Example
483///
484/// ```
485/// # #[macro_use] extern crate nix;
486/// # #[cfg(linux_android)]
487/// ioctl_write_ptr_bad!(tcsets, libc::TCSETS, libc::termios);
488/// # fn main() {}
489/// ```
490#[macro_export(local_inner_macros)]
491macro_rules! ioctl_write_ptr_bad {
492    ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
493        $(#[$attr])*
494        pub unsafe fn $name(fd: $crate::libc::c_int,
495                            data: *const $ty)
496                            -> $crate::Result<$crate::libc::c_int> {
497            unsafe {
498                convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
499            }
500        }
501    )
502}
503
504cfg_if! {
505    if #[cfg(freebsdlike)] {
506        /// Generates a wrapper function for a ioctl that writes an integer to the kernel.
507        ///
508        /// The arguments to this macro are:
509        ///
510        /// * The function name
511        /// * The ioctl identifier
512        /// * The ioctl sequence number
513        ///
514        /// The generated function has the following signature:
515        ///
516        /// ```rust,ignore
517        /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int>
518        /// ```
519        ///
520        /// `nix::sys::ioctl::ioctl_param_type` depends on the OS:
521        /// *   BSD - `libc::c_int`
522        /// *   Linux - `libc::c_ulong`
523        ///
524        /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
525        ///
526        /// # Example
527        ///
528        /// ```
529        /// # #[macro_use] extern crate nix;
530        /// ioctl_write_int!(vt_activate, b'v', 4);
531        /// # fn main() {}
532        /// ```
533        #[macro_export(local_inner_macros)]
534        macro_rules! ioctl_write_int {
535            ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => (
536                $(#[$attr])*
537                pub unsafe fn $name(fd: $crate::libc::c_int,
538                                    data: $crate::sys::ioctl::ioctl_param_type)
539                                    -> $crate::Result<$crate::libc::c_int> {
540                    unsafe {
541                        convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write_int!($ioty, $nr) as $crate::sys::ioctl::ioctl_num_type, data))
542                    }
543                }
544            )
545        }
546    } else {
547        /// Generates a wrapper function for a ioctl that writes an integer to the kernel.
548        ///
549        /// The arguments to this macro are:
550        ///
551        /// * The function name
552        /// * The ioctl identifier
553        /// * The ioctl sequence number
554        ///
555        /// The generated function has the following signature:
556        ///
557        /// ```rust,ignore
558        /// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: nix::sys::ioctl::ioctl_param_type) -> Result<libc::c_int>
559        /// ```
560        ///
561        /// `nix::sys::ioctl::ioctl_param_type` depends on the OS:
562        /// *   BSD - `libc::c_int`
563        /// *   Linux - `libc::c_ulong`
564        ///
565        /// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
566        ///
567        /// # Example
568        ///
569        /// ```
570        /// # #[macro_use] extern crate nix;
571        /// const HCI_IOC_MAGIC: u8 = b'k';
572        /// const HCI_IOC_HCIDEVUP: u8 = 1;
573        /// ioctl_write_int!(hci_dev_up, HCI_IOC_MAGIC, HCI_IOC_HCIDEVUP);
574        /// # fn main() {}
575        /// ```
576        #[macro_export(local_inner_macros)]
577        macro_rules! ioctl_write_int {
578            ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr) => (
579                $(#[$attr])*
580                pub unsafe fn $name(fd: $crate::libc::c_int,
581                                    data: $crate::sys::ioctl::ioctl_param_type)
582                                    -> $crate::Result<$crate::libc::c_int> {
583                    unsafe {
584                        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))
585                    }
586                }
587            )
588        }
589    }
590}
591
592/// Generates a wrapper function for a "bad" ioctl that writes an integer to the kernel.
593///
594/// The arguments to this macro are:
595///
596/// * The function name
597/// * The ioctl request code
598///
599/// The generated function has the following signature:
600///
601/// ```rust,ignore
602/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: libc::c_int) -> Result<libc::c_int>
603/// ```
604///
605/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
606///
607/// # Examples
608///
609/// ```
610/// # #[macro_use] extern crate nix;
611/// # #[cfg(linux_android)]
612/// ioctl_write_int_bad!(tcsbrk, libc::TCSBRK);
613/// # fn main() {}
614/// ```
615///
616/// ```rust
617/// # #[macro_use] extern crate nix;
618/// const KVMIO: u8 = 0xAE;
619/// ioctl_write_int_bad!(kvm_create_vm, request_code_none!(KVMIO, 0x03));
620/// # fn main() {}
621/// ```
622#[macro_export(local_inner_macros)]
623macro_rules! ioctl_write_int_bad {
624    ($(#[$attr:meta])* $name:ident, $nr:expr) => (
625        $(#[$attr])*
626        pub unsafe fn $name(fd: $crate::libc::c_int,
627                            data: $crate::libc::c_int)
628                            -> $crate::Result<$crate::libc::c_int> {
629            unsafe {
630                convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
631            }
632        }
633    )
634}
635
636/// Generates a wrapper function for an ioctl that reads and writes data to the kernel.
637///
638/// The arguments to this macro are:
639///
640/// * The function name
641/// * The ioctl identifier
642/// * The ioctl sequence number
643/// * The data type passed by this ioctl
644///
645/// The generated function has the following signature:
646///
647/// ```rust,ignore
648/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
649/// ```
650///
651/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
652///
653/// # Example
654///
655/// ```
656/// # #[macro_use] extern crate nix;
657/// # pub struct v4l2_audio {}
658/// ioctl_readwrite!(enum_audio, b'V', 65, v4l2_audio);
659/// # fn main() {}
660/// ```
661#[macro_export(local_inner_macros)]
662macro_rules! ioctl_readwrite {
663    ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
664        $(#[$attr])*
665        pub unsafe fn $name(fd: $crate::libc::c_int,
666                            data: *mut $ty)
667                            -> $crate::Result<$crate::libc::c_int> {
668            let ioty = $ioty;
669            let nr = $nr;
670            unsafe {
671                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))
672            }
673        }
674    )
675}
676
677/// Generates a wrapper function for a "bad" ioctl that reads and writes data to the kernel.
678///
679/// The arguments to this macro are:
680///
681/// * The function name
682/// * The ioctl request code
683/// * The data type passed by this ioctl
684///
685/// The generated function has the following signature:
686///
687/// ```rust,ignore
688/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: *mut DATA_TYPE) -> Result<libc::c_int>
689/// ```
690///
691/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
692// TODO: Find an example for ioctl_readwrite_bad
693#[macro_export(local_inner_macros)]
694macro_rules! ioctl_readwrite_bad {
695    ($(#[$attr:meta])* $name:ident, $nr:expr, $ty:ty) => (
696        $(#[$attr])*
697        pub unsafe fn $name(fd: $crate::libc::c_int,
698                            data: *mut $ty)
699                            -> $crate::Result<$crate::libc::c_int> {
700            unsafe {
701                convert_ioctl_res!($crate::libc::ioctl(fd, $nr as $crate::sys::ioctl::ioctl_num_type, data))
702            }
703        }
704    )
705}
706
707/// Generates a wrapper function for an ioctl that reads an array of elements from the kernel.
708///
709/// The arguments to this macro are:
710///
711/// * The function name
712/// * The ioctl identifier
713/// * The ioctl sequence number
714/// * The data type passed by this ioctl
715///
716/// The generated function has the following signature:
717///
718/// ```rust,ignore
719/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int>
720/// ```
721///
722/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
723// TODO: Find an example for ioctl_read_buf
724#[macro_export(local_inner_macros)]
725macro_rules! ioctl_read_buf {
726    ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
727        $(#[$attr])*
728        pub unsafe fn $name(fd: $crate::libc::c_int,
729                            data: &mut [$ty])
730                            -> $crate::Result<$crate::libc::c_int> {
731            unsafe {
732                convert_ioctl_res!($crate::libc::ioctl(fd, request_code_read!($ioty, $nr, ::std::mem::size_of_val(data)) as $crate::sys::ioctl::ioctl_num_type, data.as_mut_ptr()))
733            }
734        }
735    )
736}
737
738/// Generates a wrapper function for an ioctl that writes an array of elements to the kernel.
739///
740/// The arguments to this macro are:
741///
742/// * The function name
743/// * The ioctl identifier
744/// * The ioctl sequence number
745/// * The data type passed by this ioctl
746///
747/// The generated function has the following signature:
748///
749/// ```rust,ignore
750/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &[DATA_TYPE]) -> Result<libc::c_int>
751/// ```
752///
753/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
754///
755/// # Examples
756///
757/// ```
758/// # #[macro_use] extern crate nix;
759/// const SPI_IOC_MAGIC: u8 = b'k'; // Defined in linux/spi/spidev.h
760/// const SPI_IOC_TYPE_MESSAGE: u8 = 0;
761/// # pub struct spi_ioc_transfer(u64);
762/// ioctl_write_buf!(spi_transfer, SPI_IOC_MAGIC, SPI_IOC_TYPE_MESSAGE, spi_ioc_transfer);
763/// # fn main() {}
764/// ```
765#[macro_export(local_inner_macros)]
766macro_rules! ioctl_write_buf {
767    ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
768        $(#[$attr])*
769        pub unsafe fn $name(fd: $crate::libc::c_int,
770                            data: &[$ty])
771                            -> $crate::Result<$crate::libc::c_int> {
772            unsafe {
773                convert_ioctl_res!($crate::libc::ioctl(fd, request_code_write!($ioty, $nr, ::std::mem::size_of_val(data)) as $crate::sys::ioctl::ioctl_num_type, data.as_ptr()))
774            }
775        }
776    )
777}
778
779/// Generates a wrapper function for an ioctl that reads and writes an array of elements to the kernel.
780///
781/// The arguments to this macro are:
782///
783/// * The function name
784/// * The ioctl identifier
785/// * The ioctl sequence number
786/// * The data type passed by this ioctl
787///
788/// The generated function has the following signature:
789///
790/// ```rust,ignore
791/// pub unsafe fn FUNCTION_NAME(fd: libc::c_int, data: &mut [DATA_TYPE]) -> Result<libc::c_int>
792/// ```
793///
794/// For a more in-depth explanation of ioctls, see [`::sys::ioctl`](sys/ioctl/index.html).
795// TODO: Find an example for readwrite_buf
796#[macro_export(local_inner_macros)]
797macro_rules! ioctl_readwrite_buf {
798    ($(#[$attr:meta])* $name:ident, $ioty:expr, $nr:expr, $ty:ty) => (
799        $(#[$attr])*
800        pub unsafe fn $name(fd: $crate::libc::c_int,
801                            data: &mut [$ty])
802                            -> $crate::Result<$crate::libc::c_int> {
803            unsafe {
804                convert_ioctl_res!($crate::libc::ioctl(fd, request_code_readwrite!($ioty, $nr, ::std::mem::size_of_val(data)) as $crate::sys::ioctl::ioctl_num_type, data.as_mut_ptr()))
805            }
806        }
807    )
808}